Merge branch 'master' into xray_in_solid_view

This commit is contained in:
Ghostkeeper 2020-03-24 21:45:48 +01:00
commit 0150f37937
No known key found for this signature in database
GPG key ID: D2A8871EE34EC59A
315 changed files with 33845 additions and 1731 deletions

View file

@ -5,8 +5,8 @@ include(GNUInstallDirs)
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_SCRIPTS_DIR "${URANIUM_DIR}/scripts" CACHE DIRECTORY "The location of the scripts directory 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 PATH "The location of the scripts directory of the Uranium repository")
# Tests
include(CuraTests)

View file

@ -4,12 +4,11 @@ from typing import Optional, Dict, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
from UM.i18n import i18nCatalog
from UM.Message import Message
from cura import UltimakerCloudAuthentication
from UM.i18n import i18nCatalog
from cura.OAuth2.AuthorizationService import AuthorizationService
from cura.OAuth2.Models import OAuth2Settings
from cura.UltimakerCloud import UltimakerCloudAuthentication
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication

View file

@ -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.
from typing import List, Optional
@ -30,7 +30,7 @@ LocationSuggestion = namedtuple("LocationSuggestion", ["x", "y", "penalty_points
class Arrange:
build_volume = None # type: Optional[BuildVolume]
def __init__(self, x, y, offset_x, offset_y, scale= 0.5):
def __init__(self, x, y, offset_x, offset_y, scale = 0.5):
self._scale = scale # convert input coordinates to arrange coordinates
world_x, world_y = int(x * self._scale), int(y * self._scale)
self._shape = (world_y, world_x)
@ -173,7 +173,10 @@ class Arrange:
def bestSpot(self, shape_arr, start_prio = 0, step = 1):
start_idx_list = numpy.where(self._priority_unique_values == start_prio)
if start_idx_list:
start_idx = start_idx_list[0][0]
try:
start_idx = start_idx_list[0][0]
except IndexError:
start_idx = 0
else:
start_idx = 0
for priority in self._priority_unique_values[start_idx::step]:

View file

@ -7,71 +7,52 @@ import time
from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any
import numpy
from PyQt5.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
from PyQt5.QtGui import QColor, QIcon
from PyQt5.QtWidgets import QMessageBox
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.Decorators import override
from UM.FlameProfiler import pyqtSlot
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.Matrix import Matrix
from UM.Math.Quaternion import Quaternion
from UM.Math.Vector import Vector
from UM.Mesh.ReadMeshJob import ReadMeshJob
from UM.Message import Message
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation
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.GroupDecorator import GroupDecorator
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode
from UM.Scene.Selection import Selection
from UM.Scene.ToolHandle import ToolHandle
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
from UM.Settings.SettingFunction import SettingFunction
from UM.Settings.Validator import Validator
from UM.View.SelectionPass import SelectionPass # For typing.
from UM.Workspace.WorkspaceReader import WorkspaceReader
from UM.i18n import i18nCatalog
from cura import ApplicationMetadata
from cura.API import CuraAPI
from cura.Arranging.Arrange import Arrange
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
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.Models.BuildPlateModel import BuildPlateModel
from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
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.GenericMaterialsModel import GenericMaterialsModel
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.MaterialManagementModel import MaterialManagementModel
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.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel
from cura.Machines.Models.UserChangesModel import UserChangesModel
from cura.Machines.Models.IntentModel import IntentModel
from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
from cura.Operations.SetParentOperation import SetParentOperation
from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
import cura.Settings.cura_empty_instance_containers
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
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.CuraContainerRegistry import CuraContainerRegistry
from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
from cura.Settings.ExtruderManager import ExtruderManager
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.MachineNameValidator import MachineNameValidator
from cura.Settings.IntentManager import IntentManager
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
from cura.UI import CuraSplashScreen, MachineActionManager, PrintInformation
from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel
from cura.UI.MachineSettingsManager import MachineSettingsManager
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.TextManager import TextManager
from cura.UI.WelcomePagesModel import WelcomePagesModel
from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel
from cura.UltimakerCloud import UltimakerCloudAuthentication
from cura.Utils.NetworkingUtil import NetworkingUtil
from .SingleInstance import SingleInstance
from .AutoSave import AutoSave
from . import PlatformPhysics
from . import BuildVolume
from . import CameraAnimation
from . import CuraActions
from . import PlatformPhysics
from . import PrintJobPreviewImageProvider
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
from cura import ApplicationMetadata, UltimakerCloudAuthentication
from cura.Settings.GlobalStack import GlobalStack
from .AutoSave import AutoSave
from .SingleInstance import SingleInstance
if TYPE_CHECKING:
from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer

View file

@ -2,6 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
from typing import Set
import cura.CuraApplication
from UM.Logger import Logger
@ -23,7 +24,7 @@ class QualitySettingsModel(ListModel):
GLOBAL_STACK_POSITION = -1
def __init__(self, parent = None):
def __init__(self, parent = None) -> None:
super().__init__(parent = parent)
self.addRoleName(self.KeyRole, "key")
@ -38,7 +39,9 @@ class QualitySettingsModel(ListModel):
self._application = cura.CuraApplication.CuraApplication.getInstance()
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._i18n_catalog = None
@ -47,14 +50,14 @@ class QualitySettingsModel(ListModel):
selectedPositionChanged = pyqtSignal()
selectedQualityItemChanged = pyqtSignal()
def setSelectedPosition(self, selected_position):
def setSelectedPosition(self, selected_position: int) -> None:
if selected_position != self._selected_position:
self._selected_position = selected_position
self.selectedPositionChanged.emit()
self._update()
@pyqtProperty(int, fset = setSelectedPosition, notify = selectedPositionChanged)
def selectedPosition(self):
def selectedPosition(self) -> int:
return self._selected_position
def setSelectedQualityItem(self, selected_quality_item):
@ -67,7 +70,7 @@ class QualitySettingsModel(ListModel):
def selectedQualityItem(self):
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__))
if not self._selected_quality_item:
@ -83,7 +86,7 @@ class QualitySettingsModel(ListModel):
quality_changes_group = self._selected_quality_item["quality_changes_group"]
quality_node = None
settings_keys = set()
settings_keys = set() # type: Set[str]
if quality_group:
if self._selected_position == self.GLOBAL_STACK_POSITION:
quality_node = quality_group.node_for_global

View file

@ -36,8 +36,10 @@ class ConvexHullDecorator(SceneNodeDecorator):
# Make sure the timer is created on the main thread
self._recompute_convex_hull_timer = None # type: Optional[QTimer]
self._timer_scheduled_to_be_created = False
from cura.CuraApplication import CuraApplication
if CuraApplication.getInstance() is not None:
self._timer_scheduled_to_be_created = True
CuraApplication.getInstance().callLater(self.createRecomputeConvexHullTimer)
self._raft_thickness = 0.0
@ -171,7 +173,12 @@ class ConvexHullDecorator(SceneNodeDecorator):
if self._recompute_convex_hull_timer is not None:
self._recompute_convex_hull_timer.start()
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:
controller = Application.getInstance().getController()

View file

@ -239,6 +239,8 @@ class ContainerManager(QObject):
container_type = container_registry.getContainerForMimeType(mime_type)
if not container_type:
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 = container_registry.uniqueName(container_id)

View file

@ -58,7 +58,10 @@ class CuraStackBuilder:
# Create ExtruderStacks
extruder_dict = machine_definition.getMetaDataEntry("machine_extruder_trains")
for position in extruder_dict:
cls.createExtruderStackWithDefaultSetup(new_global_stack, position)
try:
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.
registry.addContainer(new_extruder)

View file

@ -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.
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()
## 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
# \param definition_id \type{str} definition id that needs to look for
@ -336,9 +347,9 @@ class MachineManager(QObject):
return cast(GlobalStack, machine)
return None
@pyqtSlot(str)
@pyqtSlot(str, str)
def addMachine(self, definition_id: str, name: Optional[str] = None) -> None:
@pyqtSlot(str, result=bool)
@pyqtSlot(str, str, result = bool)
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)
if name is None:
definitions = CuraContainerRegistry.getInstance().findDefinitionContainers(id = definition_id)
@ -353,6 +364,8 @@ class MachineManager(QObject):
self.setActiveMachine(new_stack.getId())
else:
Logger.log("w", "Failed creating a new machine!")
return False
return True
def _checkStacksHaveErrors(self) -> bool:
time_start = time.time()
@ -1507,7 +1520,17 @@ class MachineManager(QObject):
if quality_id == empty_quality_container.getId():
extruder.intent = empty_intent_container
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():
if intent_node.intent_category == intent_category: # Found an intent with the correct category.

View file

@ -28,7 +28,11 @@ class TextManager(QObject):
def _loadChangeLogText(self) -> str:
# Load change log texts and organize them with a dict
file_path = Resources.getPath(Resources.Texts, "change_log.txt")
try:
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]]]
with open(file_path, "r", encoding = "utf-8") as f:
open_version = None # type: Optional[Version]

View file

@ -6,17 +6,20 @@ from cura.API import Account
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):
"""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):
super().__init__(application)
api = application.getCuraAPI()
self._account = api.account # type: Account
def request_hook(self, request: QNetworkRequest):
super().request_hook(request)
def requestHook(self, request: QNetworkRequest):
super().requestHook(request)
token = self._account.accessToken
if not self._account.isLoggedIn or token is None:
Logger.warning("Cannot add authorization to Cloud Api request")
@ -25,4 +28,4 @@ class UltimakerCloudScope(DefaultUserAgentScope):
header_dict = {
"Authorization": "Bearer {}".format(token)
}
self.add_headers(request, header_dict)
self.addHeaders(request, header_dict)

View file

View file

@ -1,12 +1,20 @@
#!/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.
# 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 faulthandler
import os
import sys
# Workaround for a race condition on certain systems where there
# is a race condition between Arcus and PyQt. Importing Arcus
@ -15,6 +23,8 @@ import sys
import Arcus # @UnusedImport
import Savitar # @UnusedImport
from PyQt5.QtNetwork import QSslConfiguration, QSslSocket
from UM.Platform import Platform
from cura import ApplicationMetadata
from cura.ApplicationMetadata import CuraAppName
@ -51,13 +61,16 @@ if with_sentry_sdk:
except IndexError:
pass
# Errors to be ignored by Sentry
ignore_errors = [KeyboardInterrupt, MemoryError]
sentry_sdk.init("https://5034bf0054fb4b889f82896326e79b13@sentry.io/1821564",
before_send = CrashHandler.sentryBeforeSend,
environment = sentry_env,
release = "cura%s" % ApplicationMetadata.CuraVersion,
default_integrations = False,
max_breadcrumbs = 300,
server_name = "cura")
server_name = "cura",
ignore_errors = ignore_errors)
if not known_args["debug"]:
def get_cura_dir_path():
@ -170,9 +183,9 @@ def exceptHook(hook_type, value, traceback):
# Set exception hook to use the crash dialog handler
sys.excepthook = exceptHook
# 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)
elif sys.stdout:
elif sys.stdout and not sys.stdout.closed:
faulthandler.enable(file = sys.stdout, all_threads = True)
from cura.CuraApplication import CuraApplication
@ -209,5 +222,10 @@ if Platform.isLinux() and getattr(sys, "frozen", False):
import trimesh.exchange.load
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.run()

View file

@ -86,7 +86,7 @@ class ThreeMFReader(MeshReader):
## Convenience function that converts a SceneNode object (as obtained from libSavitar) to a 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
node_name = "Object %s" % self._object_count
@ -104,6 +104,10 @@ class ThreeMFReader(MeshReader):
vertices = numpy.resize(data, (int(data.size / 3), 3))
mesh_builder.setVertices(vertices)
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()
if len(mesh_data.getVertices()):
@ -171,7 +175,7 @@ class ThreeMFReader(MeshReader):
scene_3mf = parser.parse(archive.open("3D/3dmodel.model").read())
self._unit = scene_3mf.getUnit()
for node in scene_3mf.getSceneNodes():
um_node = self._convertSavitarNodeToUMNode(node)
um_node = self._convertSavitarNodeToUMNode(node, file_name)
if um_node is None:
continue
# compensate for original center position, if object(s) is/are not around its zero position

View file

@ -285,13 +285,13 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
serialized = archive.open(instance_container_file_name).read().decode("utf-8")
# 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)
container_type = parser["metadata"]["type"]
if container_type not in ("quality", "variant"):
serialized = InstanceContainer._updateSerialized(serialized, instance_container_file_name)
parser = ConfigParser(interpolation = None)
parser = ConfigParser(interpolation = None, comment_prefixes = ())
parser.read_string(serialized)
container_info = ContainerInfo(instance_container_file_name, serialized, parser)
instance_container_info_dict[container_id] = container_info

View file

@ -118,7 +118,7 @@ class AMFReader(MeshReader):
mesh.merge_vertices()
mesh.remove_unreferenced_vertices()
mesh.fix_normals()
mesh_data = self._toMeshData(mesh)
mesh_data = self._toMeshData(mesh, file_name)
new_node = CuraSceneNode()
new_node.setSelectable(True)
@ -147,7 +147,13 @@ class AMFReader(MeshReader):
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_vertices = tri_node.vertices
@ -169,5 +175,5 @@ class AMFReader(MeshReader):
indices = numpy.asarray(indices, dtype = numpy.int32)
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

View 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()

View file

@ -1,90 +1,70 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import base64
import hashlib
from datetime import datetime
from tempfile import NamedTemporaryFile
from typing import Any, Optional, List, Dict
from typing import Any, Optional, List, Dict, Callable
import requests
from PyQt5.QtNetwork import QNetworkReply
from UM.Logger import Logger
from UM.Message import Message
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 .UploadBackupJob import UploadBackupJob
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
from .CreateBackupJob import CreateBackupJob
from .RestoreBackupJob import RestoreBackupJob
from .Settings import Settings
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
## The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling.
@signalemitter
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)
# Emit signal when restoring backup started or finished.
restoringStateChanged = Signal()
"""Emits signal when restoring backup started or finished."""
# Emit signal when creating backup started or finished.
creatingStateChanged = Signal()
"""Emits signal when creating backup started or finished."""
def __init__(self) -> None:
self._cura_api = CuraApplication.getInstance().getCuraAPI()
self._json_cloud_scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance()))
def getBackups(self) -> List[Dict[str, Any]]:
access_token = self._cura_api.account.accessToken
if not access_token:
Logger.log("w", "Could not get access token.")
return []
try:
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 []
def getBackups(self, changed: Callable[[List[Dict[str, Any]]], None]) -> None:
def callback(reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
if error is not None:
Logger.log("w", "Could not get backups: " + str(error))
changed([])
return
# HTTP status 300s mean redirection. 400s and 500s are errors.
# 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 = HttpRequestManager.readJSON(reply)
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))
changed([]) # empty list of backups
return
backup_list_response = backup_list_request.json()
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))
return []
changed(backup_list_response["data"])
return backup_list_response["data"]
HttpRequestManager.getInstance().get(
self.BACKUP_URL,
callback= callback,
error_callback = callback,
scope=self._json_cloud_scope
)
def createBackup(self) -> None:
self.creatingStateChanged.emit(is_creating = True)
# 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 = CreateBackupJob(self.BACKUP_URL)
upload_backup_job.finished.connect(self._onUploadFinished)
upload_backup_job.start()
def _onUploadFinished(self, job: "UploadBackupJob") -> None:
def _onUploadFinished(self, job: "CreateBackupJob") -> None:
if job.backup_upload_error_message != "":
# 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)
@ -96,96 +76,38 @@ class DriveApiService:
download_url = backup.get("download_url")
if not download_url:
# If there is no download URL, we can't restore the backup.
return self._emitRestoreError()
Logger.warning("backup download_url is missing. Aborting backup.")
self.restoringStateChanged.emit(is_restoring = False,
error_message = catalog.i18nc("@info:backup_status",
"There was an error trying to restore your backup."))
return
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()
restore_backup_job = RestoreBackupJob(backup)
restore_backup_job.finished.connect(self._onRestoreFinished)
restore_backup_job.start()
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()
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)
# 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)
def deleteBackup(self, backup_id: str, finished_callable: Callable[[bool], None]):
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()
def finishedCallback(reply: QNetworkReply, ca: Callable[[bool], None] = finished_callable) -> None:
self._onDeleteRequestCompleted(reply, ca)
# 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 errorCallback(reply: QNetworkReply, error: QNetworkReply.NetworkError, ca: Callable[[bool], None] = finished_callable) -> None:
self._onDeleteRequestCompleted(reply, ca, error)
def _emitRestoreError(self) -> None:
self.restoringStateChanged.emit(is_restoring = False,
error_message = catalog.i18nc("@info:backup_status",
"There was an error trying to restore your backup."))
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
def _verifyMd5Hash(file_path: str, known_hash: str) -> bool:
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
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"]
def _onDeleteRequestCompleted(reply: QNetworkReply, callable: Callable[[bool], None], error: Optional["QNetworkReply.NetworkError"] = None) -> None:
callable(HttpRequestManager.replyIndicatesSuccess(reply, error))

View file

@ -133,7 +133,10 @@ class DrivePluginExtension(QObject, Extension):
@pyqtSlot(name = "refreshBackups")
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()
@pyqtProperty(bool, notify = restoringStateChanged)
@ -158,5 +161,8 @@ class DrivePluginExtension(QObject, Extension):
@pyqtSlot(str, name = "deleteBackup")
def deleteBackup(self, backup_id: str) -> None:
self._drive_api_service.deleteBackup(backup_id)
self.refreshBackups()
self._drive_api_service.deleteBackup(backup_id, self._backupDeletedCallback)
def _backupDeletedCallback(self, success: bool):
if success:
self.refreshBackups()

View 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

View file

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from cura import UltimakerCloudAuthentication
from cura.UltimakerCloud import UltimakerCloudAuthentication
class Settings:

View file

@ -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)

View file

@ -421,7 +421,10 @@ class CuraEngineBackend(QObject, Backend):
if job.getResult() == StartJobResult.NothingToSlice:
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"))
self._error_message.show()
self.setState(BackendState.Error)

View file

@ -422,13 +422,14 @@ class StartSliceJob(Job):
# Pre-compute material material_bed_temp_prepend and material_print_temp_prepend
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"]
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
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}
settings["material_print_temp_prepend"] = re.search(pattern, start_gcode) == None
# 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
initial_extruder_stack = CuraApplication.getInstance().getExtruderManager().getUsedExtruderStacks()[0]

View file

@ -44,6 +44,7 @@ class FirmwareUpdateCheckerJob(Job):
try:
# CURA-6698 Create an SSL context and use certifi CA certificates for verification.
context = ssl.SSLContext(protocol = ssl.PROTOCOL_TLSv1_2)
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(cafile = certifi.where())
request = urllib.request.Request(url, headers = self._headers)

View file

@ -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.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.
#
# If you're zipping g-code, you might as well use gzip!
@ -39,9 +25,7 @@ class GCodeGzReader(MeshReader):
def _read(self, file_name):
with open(file_name, "rb") as file:
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)
result = PluginRegistry.getInstance().getPluginObject("GCodeReader").readFromStream(uncompressed_gcode, file_name)

View file

@ -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.
import numpy
@ -96,7 +96,7 @@ class ImageReader(MeshReader):
texel_width = 1.0 / (width_minus_one) * scale_vector.x
texel_height = 1.0 / (height_minus_one) * scale_vector.z
height_data = numpy.zeros((height, width), dtype=numpy.float32)
height_data = numpy.zeros((height, width), dtype = numpy.float32)
for x in range(0, width):
for y in range(0, height):
@ -112,7 +112,7 @@ class ImageReader(MeshReader):
height_data = 1 - height_data
for _ in range(0, blur_iterations):
copy = numpy.pad(height_data, ((1, 1), (1, 1)), mode= "edge")
copy = numpy.pad(height_data, ((1, 1), (1, 1)), mode = "edge")
height_data += copy[1:-1, 2:]
height_data += copy[1:-1, :-2]
@ -165,7 +165,7 @@ class ImageReader(MeshReader):
offsetsz = numpy.array(offsetsz, numpy.float32).reshape(-1, 1) * texel_height
# offsets for each texel quad
heightmap_vertex_offsets = numpy.concatenate([offsetsx, numpy.zeros((offsetsx.shape[0], offsetsx.shape[1]), dtype=numpy.float32), offsetsz], 1)
heightmap_vertex_offsets = numpy.concatenate([offsetsx, numpy.zeros((offsetsx.shape[0], offsetsx.shape[1]), dtype = numpy.float32), offsetsz], 1)
heightmap_vertices += heightmap_vertex_offsets.repeat(6, 0).reshape(-1, 6, 3)
# apply height data to y values
@ -174,7 +174,7 @@ class ImageReader(MeshReader):
heightmap_vertices[:, 2, 1] = heightmap_vertices[:, 3, 1] = height_data[1:, 1:].reshape(-1)
heightmap_vertices[:, 4, 1] = height_data[:-1, 1:].reshape(-1)
heightmap_indices = numpy.array(numpy.mgrid[0:heightmap_face_count * 3], dtype=numpy.int32).reshape(-1, 3)
heightmap_indices = numpy.array(numpy.mgrid[0:heightmap_face_count * 3], dtype = numpy.int32).reshape(-1, 3)
mesh._vertices[0:(heightmap_vertices.size // 3), :] = heightmap_vertices.reshape(-1, 3)
mesh._indices[0:(heightmap_indices.size // 3), :] = heightmap_indices
@ -223,7 +223,7 @@ class ImageReader(MeshReader):
mesh.addFaceByPoints(geo_width, 0, y, geo_width, 0, ny, geo_width, he1, ny)
mesh.addFaceByPoints(geo_width, he1, ny, geo_width, he0, y, geo_width, 0, y)
mesh.calculateNormals(fast=True)
mesh.calculateNormals(fast = True)
scene_node.setMeshData(mesh.build())

View file

@ -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.
import os
@ -33,9 +33,9 @@ class ImageReaderUI(QObject):
self.base_height = 0.4
self.peak_height = 2.5
self.smoothing = 1
self.lighter_is_higher = False;
self.use_transparency_model = True;
self.transmittance_1mm = 50.0; # based on pearl PLA
self.lighter_is_higher = False
self.use_transparency_model = True
self.transmittance_1mm = 50.0 # based on pearl PLA
self._ui_lock = threading.Lock()
self._cancelled = False
@ -85,7 +85,7 @@ class ImageReaderUI(QObject):
Logger.log("d", "Creating ImageReader config UI")
path = os.path.join(PluginRegistry.getInstance().getPluginPath("ImageReader"), "ConfigUI.qml")
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
@pyqtSlot()

View file

@ -107,7 +107,7 @@ Item
labelWidth: base.labelWidth
controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm")
allowNegativeValue: true
minimum: Number.NEGATIVE_INFINITY
forceUpdateOnChangeFunction: forceUpdateFunction
}
@ -122,7 +122,7 @@ Item
labelWidth: base.labelWidth
controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm")
allowNegativeValue: true
minimum: Number.NEGATIVE_INFINITY
forceUpdateOnChangeFunction: forceUpdateFunction
}

View file

@ -72,6 +72,7 @@ Item
labelWidth: base.labelWidth
controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm")
maximum: 2000000
forceUpdateOnChangeFunction: forceUpdateFunction
}
@ -86,6 +87,7 @@ Item
labelWidth: base.labelWidth
controlWidth: base.controlWidth
unitText: catalog.i18nc("@label", "mm")
maximum: 2000000
forceUpdateOnChangeFunction: forceUpdateFunction
}
@ -204,8 +206,8 @@ Item
axisName: "x"
axisMinOrMax: "min"
allowNegativeValue: true
allowPositiveValue: false
minimum: Number.NEGATIVE_INFINITY
maximum: 0
forceUpdateOnChangeFunction: forceUpdateFunction
}
@ -224,8 +226,8 @@ Item
axisName: "y"
axisMinOrMax: "min"
allowNegativeValue: true
allowPositiveValue: false
minimum: Number.NEGATIVE_INFINITY
maximum: 0
forceUpdateOnChangeFunction: forceUpdateFunction
}
@ -244,8 +246,6 @@ Item
axisName: "x"
axisMinOrMax: "max"
allowNegativeValue: false
allowPositiveValue: true
forceUpdateOnChangeFunction: forceUpdateFunction
}
@ -266,8 +266,6 @@ Item
axisName: "y"
axisMinOrMax: "max"
allowNegativeValue: false
allowPositiveValue: true
forceUpdateOnChangeFunction: forceUpdateFunction
}

View file

@ -73,6 +73,8 @@ class ModelChecker(QObject, Extension):
# Check node material shrinkage and bounding box size
for node in self.sliceableNodes():
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
# has not done yet.

View file

@ -71,7 +71,7 @@ class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHand
# Add all instances that are not added, but are in visibility list
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)
if definition:
new_instance = SettingInstance(definition, settings)

View file

@ -49,18 +49,6 @@ Item
visibility_handler.addSkipResetSetting(currentMeshType)
}
function setOverhangsMeshType()
{
if (infillOnlyCheckbox.checked)
{
setMeshType(infillMeshType)
}
else
{
setMeshType(cuttingMeshType)
}
}
function setMeshType(type)
{
UM.ActiveTool.setProperty("MeshType", type)
@ -140,26 +128,43 @@ Item
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
onClicked: setOverhangsMeshType()
onActivated:
{
if (index == 0){
setMeshType(infillMeshType)
} else {
setMeshType(cuttingMeshType)
}
}
Binding
{
target: infillOnlyCheckbox
property: "checked"
value: currentMeshType === infillMeshType
target: infillOnlyComboBox
property: "currentIndex"
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.
// It kinda looks ugly otherwise (big panel, no content on it)

View file

@ -82,6 +82,7 @@ class PerObjectSettingsTool(Tool):
selected_object.addDecorator(SettingOverrideDecorator())
stack = selected_object.callDecoration("getStack")
settings_visibility_changed = False
settings = stack.getTop()
for property_key in ["infill_mesh", "cutting_mesh", "support_mesh", "anti_overhang_mesh"]:
if property_key != mesh_type:
@ -97,17 +98,20 @@ class PerObjectSettingsTool(Tool):
for property_key in ["top_bottom_thickness", "wall_thickness"]:
if mesh_type == "infill_mesh":
if not settings.getInstance(property_key):
if settings.getInstance(property_key) is None:
definition = stack.getSettingDefinition(property_key)
new_instance = SettingInstance(definition, settings)
new_instance.setProperty("value", 0)
new_instance.resetState() # Ensure that the state is not seen as a user state.
settings.addInstance(new_instance)
visible = self.visibility_handler.getVisible()
visible.add(property_key)
self.visibility_handler.setVisible(visible)
settings_visibility_changed = True
elif old_mesh_type == "infill_mesh" and settings.getInstance(property_key) and settings.getProperty(property_key, "value") == 0:
settings.removeInstance(property_key)
settings_visibility_changed = True
if settings_visibility_changed:
self.visibility_handler.forceVisibilityChanged()
self.propertyChanged.emit()
return True

View file

@ -484,15 +484,53 @@ UM.Dialog
onClicked: dialog.accept()
}
Cura.SecondaryButton
Item
{
objectName: "postProcessingSaveAreaButton"
visible: activeScriptsList.count > 0
height: UM.Theme.getSize("action_button").height
width: height
tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts")
onClicked: dialog.show()
iconSource: "postprocessing.svg"
fixedWidthMode: true
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()
iconSource: "postprocessing.svg"
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
}
}
}

View file

@ -6,14 +6,22 @@
#Authors of the 2-1 ColorMix plug-in / script:
# Written by John Hryb - john.hryb.4@gmail.com
##history / change-log:
##V1.0.0
## Uses -
## M163 - Set Mix Factor
## M164 - Save Mix - saves to T3 as a unique mix
import re #To perform the search and replace.
#history / change-log:
#V1.0.0 - Initial
#V1.1.0 -
# additions:
#Object number - To select individual models or all when using "one at a time" print sequence
#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.
from ..Script import Script
class ColorMix(Script):
@ -22,20 +30,28 @@ class ColorMix(Script):
def getSettingDataString(self):
return """{
"name":"ColorMix 2-1",
"name":"ColorMix 2-1 V1.2.1",
"key":"ColorMix 2-1",
"metadata": {},
"version": 2,
"settings":
{
"measurement_units":
"units_of_measurement":
{
"label": "Units of measurement",
"label": "Units",
"description": "Input value as mm or layer number.",
"type": "enum",
"options": {"mm":"mm","layer":"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":
{
"label": "Start Height",
@ -59,10 +75,10 @@ class ColorMix(Script):
"type": "float",
"default_value": 0,
"minimum_value": "0",
"minimum_value_warning": "0.1",
"enabled": "c_behavior == 'blend_value'"
"minimum_value_warning": "start_height",
"enabled": "behavior == 'blend_value'"
},
"mix_start_ratio":
"mix_start":
{
"label": "Start mix ratio",
"description": "First extruder percentage 0-100",
@ -72,7 +88,7 @@ class ColorMix(Script):
"minimum_value_warning": "0",
"maximum_value_warning": "100"
},
"mix_finish_ratio":
"mix_finish":
{
"label": "End mix ratio",
"description": "First extruder percentage 0-100 to finish blend",
@ -81,14 +97,7 @@ class ColorMix(Script):
"minimum_value": "0",
"minimum_value_warning": "0",
"maximum_value_warning": "100",
"enabled": "c_behavior == 'blend_value'"
},
"notes":
{
"label": "Notes",
"description": "A spot to put a note",
"type": "str",
"default_value": ""
"enabled": "behavior == 'blend_value'"
}
}
}"""
@ -112,52 +121,53 @@ class ColorMix(Script):
return default
def execute(self, data):
#get user variables
firstHeight = 0.0
secondHeight = 0.0
firstMix = 0.0
SecondMix = 0.0
firstHeight = self.getSettingValueByKey("start_height")
secondHeight = self.getSettingValueByKey("finish_height")
firstMix = self.getSettingValueByKey("mix_start_ratio")
SecondMix = self.getSettingValueByKey("mix_finish_ratio")
#locals
layer = 0
firstMix = self.getSettingValueByKey("mix_start")
secondMix = self.getSettingValueByKey("mix_finish")
modelOfInterest = self.getSettingValueByKey("object_number")
#get layer height
layerHeight = .2
layerHeight = 0
for active_layer in data:
lines = active_layer.split("\n")
for line in lines:
if ";Layer height: " in line:
layerHeight = self.getValue(line, ";Layer height: ", layerHeight)
break
if layerHeight != 0:
break
#default layerHeight if not found
if layerHeight == 0:
layerHeight = .2
#get layers to use
startLayer = 0
endLayer = 0
if self.getSettingValueByKey("measurement_units") == "mm":
if firstHeight == 0:
startLayer = 0
else:
startLayer = firstHeight / layerHeight
if secondHeight == 0:
endLayer = 0
else:
endLayer = secondHeight / layerHeight
else: #layer height
startLayer = firstHeight
endLayer = secondHeight
if self.getSettingValueByKey("units_of_measurement") == "mm":
startLayer = round(firstHeight / layerHeight)
endLayer = round(secondHeight / layerHeight)
else: #layer height shifts down by one for g-code
if firstHeight <= 0:
firstHeight = 1
if secondHeight <= 0:
secondHeight = 1
startLayer = firstHeight - 1
endLayer = secondHeight - 1
#see if one-shot
if self.getSettingValueByKey("behavior") == "fixed_value":
endLayer = startLayer
firstExtruderIncrements = 0
else: #blend
firstExtruderIncrements = (SecondMix - firstMix) / (endLayer - startLayer)
firstExtruderIncrements = (secondMix - firstMix) / (endLayer - startLayer)
firstExtruderValue = 0
index = 0
#start scanning
layer = -1
modelNumber = 0
for active_layer in data:
modified_gcode = ""
lineIndex = 0;
@ -169,22 +179,30 @@ class ColorMix(Script):
# find current layer
if ";LAYER:" in line:
layer = self.getValue(line, ";LAYER:", layer)
if (layer >= startLayer) and (layer <= endLayer): #find layers of interest
if lines[lineIndex + 4] == "T2": #check if needing to delete old data
del lines[(lineIndex + 1):(lineIndex + 5)]
firstExtruderValue = int(((layer - startLayer) * firstExtruderIncrements) + firstMix)
if firstExtruderValue == 100:
modified_gcode += "M163 S0 P1\n"
modified_gcode += "M163 S1 P0\n"
elif firstExtruderValue == 0:
modified_gcode += "M163 S0 P0\n"
modified_gcode += "M163 S1 P1\n"
else:
modified_gcode += "M163 S0 P0.{:02d}\n".format(firstExtruderValue)
modified_gcode += "M163 S1 P0.{:02d}\n".format(100 - firstExtruderValue)
modified_gcode += "M164 S2\n"
modified_gcode += "T2\n"
#get model number by layer 0 repeats
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)]
#add mixing commands
firstExtruderValue = int(((layer - startLayer) * firstExtruderIncrements) + firstMix)
if firstExtruderValue == 100:
modified_gcode += "M163 S0 P1\n"
modified_gcode += "M163 S1 P0\n"
elif firstExtruderValue == 0:
modified_gcode += "M163 S0 P0\n"
modified_gcode += "M163 S1 P1\n"
else:
modified_gcode += "M163 S0 P0.{:02d}\n".format(firstExtruderValue)
modified_gcode += "M163 S1 P0.{:02d}\n".format(100 - firstExtruderValue)
modified_gcode += "M164 S2\n"
modified_gcode += "T2\n"
lineIndex += 1 #for deleting index
data[index] = modified_gcode
index += 1
return data
return data

View file

@ -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.
import QtQuick 2.4

View file

@ -42,7 +42,7 @@ Item
rightMargin: UM.Theme.getSize("wide_margin").width
}
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()
}

View file

@ -1,6 +1,7 @@
from typing import Union
from cura import ApplicationMetadata, UltimakerCloudAuthentication
from cura import ApplicationMetadata
from cura.UltimakerCloud import UltimakerCloudAuthentication
class CloudApiModel:

View file

@ -1,8 +1,9 @@
from UM.Logger import Logger
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
from cura.CuraApplication import CuraApplication
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
from ..CloudApiModel import CloudApiModel
from ..UltimakerCloudScope import UltimakerCloudScope
class CloudApiClient:
@ -26,7 +27,7 @@ class CloudApiClient:
if self.__instance is not None:
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)

View file

@ -2,6 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher.
import json
from typing import List, Dict, Any
from typing import Optional
from PyQt5.QtCore import QObject
@ -11,12 +12,12 @@ from UM import i18nCatalog
from UM.Logger import Logger
from UM.Message import Message
from UM.Signal import Signal
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
from cura.CuraApplication import CuraApplication, ApplicationMetadata
from ..CloudApiModel import CloudApiModel
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
from .SubscribedPackagesModel import SubscribedPackagesModel
from ..UltimakerCloudScope import UltimakerCloudScope
from ..CloudApiModel import CloudApiModel
from typing import List, Dict, Any
class CloudPackageChecker(QObject):
def __init__(self, application: CuraApplication) -> None:
@ -24,7 +25,7 @@ class CloudPackageChecker(QObject):
self.discrepancies = Signal() # Emits SubscribedPackagesModel
self._application = application # type: CuraApplication
self._scope = UltimakerCloudScope(application)
self._scope = JsonDecoratorScope(UltimakerCloudScope(application))
self._model = SubscribedPackagesModel()
self._message = None # type: Optional[Message]
@ -111,4 +112,4 @@ class CloudPackageChecker(QObject):
def _onSyncButtonClicked(self, sync_message: Message, sync_message_action: str) -> None:
sync_message.hide()
self.discrepancies.emit(self._model)
self.discrepancies.emit(self._model)

View file

@ -12,8 +12,8 @@ from UM.Message import Message
from UM.Signal import Signal
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
from cura.CuraApplication import CuraApplication
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
from .SubscribedPackagesModel import SubscribedPackagesModel
from ..UltimakerCloudScope import UltimakerCloudScope
## Downloads a set of packages from the Ultimaker Cloud Marketplace

View file

@ -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.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from UM.Extension import Extension
from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry
from UM.Extension import Extension
from UM.i18n import i18nCatalog
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
from UM.Version import Version
from UM.i18n import i18nCatalog
from cura import ApplicationMetadata
from cura.CuraApplication import CuraApplication
from cura.Machines.ContainerTree import ContainerTree
from .CloudApiModel import CloudApiModel
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
from .AuthorsModel import AuthorsModel
from .CloudApiModel import CloudApiModel
from .CloudSync.LicenseModel import LicenseModel
from .PackagesModel import PackagesModel
from .UltimakerCloudScope import UltimakerCloudScope
if TYPE_CHECKING:
from UM.TaskManagement.HttpRequestData import HttpRequestData
@ -54,7 +52,8 @@ class Toolbox(QObject, Extension):
self._download_request_data = None # type: Optional[HttpRequestData]
self._download_progress = 0 # type: float
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._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)
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:
return self._license_dialog_plugin_file_location
@ -541,7 +540,7 @@ class Toolbox(QObject, Extension):
self._application.getHttpRequestManager().get(url,
callback = callback,
error_callback = error_callback,
scope=self._scope)
scope=self._json_scope)
@pyqtSlot(str)
def startDownload(self, url: str) -> None:
@ -554,7 +553,7 @@ class Toolbox(QObject, Extension):
callback = callback,
error_callback = error_callback,
download_progress_callback = download_progress_callback,
scope=self._scope
scope=self._cloud_scope
)
self._download_request_data = request_data

View file

@ -108,7 +108,7 @@ class TrimeshReader(MeshReader):
mesh.merge_vertices()
mesh.remove_unreferenced_vertices()
mesh.fix_normals()
mesh_data = self._toMeshData(mesh)
mesh_data = self._toMeshData(mesh, file_name)
file_base_name = os.path.basename(file_name)
new_node = CuraSceneNode()
@ -133,9 +133,10 @@ class TrimeshReader(MeshReader):
## 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) -> MeshData:
def _toMeshData(self, tri_node: trimesh.base.Trimesh, file_name: str = "") -> MeshData:
tri_faces = tri_node.faces
tri_vertices = tri_node.vertices
@ -157,5 +158,5 @@ class TrimeshReader(MeshReader):
indices = numpy.asarray(indices, dtype = numpy.int32)
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

View file

@ -9,18 +9,16 @@ from PyQt5.QtCore import QUrl
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
from UM.Logger import Logger
from cura import UltimakerCloudAuthentication
from cura.API import Account
from cura.UltimakerCloud import UltimakerCloudAuthentication
from .ToolPathUploader import ToolPathUploader
from ..Models.BaseModel import BaseModel
from ..Models.Http.CloudClusterResponse import CloudClusterResponse
from ..Models.Http.CloudError import CloudError
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.CloudPrintResponse import CloudPrintResponse
from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
## The generic type variable used to document the methods below.
CloudApiClientModel = TypeVar("CloudApiClientModel", bound=BaseModel)

View file

@ -1,6 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from time import time
import os
from typing import List, Optional, cast
from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
@ -191,8 +192,9 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
def _onPrintJobCreated(self, job: ExportFileJob) -> None:
output = job.getOutput()
self._tool_path = output # store the tool path to prevent re-uploading when printing the same file again
file_name = job.getFileName()
request = CloudPrintJobUploadRequest(
job_name=job.getFileName(),
job_name=os.path.splitext(file_name)[0],
file_size=len(output),
content_type=job.getMimeType(),
)

View file

@ -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
View 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

View file

@ -44,7 +44,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1
"value": "1"
},
"top_bottom_thickness": {
"default_value": 1

View file

@ -44,7 +44,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1
"value": "1"
},
"top_bottom_thickness": {
"default_value": 1

View file

@ -44,7 +44,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1
"value": "1"
},
"top_bottom_thickness": {
"default_value": 1

View file

@ -51,7 +51,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"speed_print": {
"default_value": 40

View file

@ -23,7 +23,7 @@
},
"material_diameter": { "default_value": 1.75 },
"layer_height_0": { "default_value": 0.2 },
"wall_thickness": { "default_value": 1.2 },
"wall_thickness": { "value": "1.2" },
"speed_print": { "default_value": 40 },
"support_enable": { "default_value": true },
"retraction_enable": { "default_value": true },

View file

@ -49,7 +49,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1
"value": "1"
},
"top_bottom_thickness": {
"default_value": 1

View file

@ -26,7 +26,7 @@
"machine_center_is_zero": { "default_value": false },
"layer_height": { "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 },
"infill_sparse_density": { "default_value": 20 },
"speed_print": { "default_value": 60 },

View file

@ -48,7 +48,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1
"value": "1"
},
"top_bottom_thickness": {
"default_value": 1

View file

@ -49,7 +49,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1
"value": "1"
},
"top_bottom_thickness": {
"default_value": 1

View file

@ -48,7 +48,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"top_bottom_thickness": {
"default_value": 1.2

View file

@ -54,7 +54,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"top_bottom_thickness": {
"default_value": 0.6

View file

@ -41,7 +41,7 @@
"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_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 }
}
}

View file

@ -46,7 +46,7 @@
"max_skin_angle_for_expansion": { "default_value": 90 },
"skin_angles": { "default_value": "[135,45]" },
"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": { "default_value": 15 },
"support_interface_pattern": { "default_value": "zigzag" },

View file

@ -7,24 +7,32 @@
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
"platform": "discoeasy200.stl",
"platform_offset": [ 105, -59, 280],
"platform": "dagoma_discoeasy200.stl",
"platform_offset": [0, -57.3, -11],
"has_machine_quality": true,
"has_materials": true,
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_discoeasy200_extruder_0"
"0": "dagoma_discoeasy200_extruder_0",
"1": "dagoma_discoeasy200_extruder_1"
}
},
"overrides": {
"machine_extruder_count": {
"default_value": 2
},
"machine_extruders_share_heater": {
"default_value": true
},
"machine_width": {
"default_value": 211
"default_value": 205
},
"machine_height": {
"default_value": 205
},
"machine_depth": {
"default_value": 211
"default_value": 205
},
"machine_center_is_zero": {
"default_value": false
@ -66,6 +74,9 @@
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
}
}
}

View 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
}
}
}

View file

@ -7,10 +7,11 @@
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
"platform": "neva.stl",
"platform_offset": [ 0, 0, 0],
"platform": "dagoma_magis.stl",
"platform_offset": [0, -28, -35],
"has_machine_quality": true,
"has_materials": true,
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_magis_extruder_0"
@ -69,6 +70,9 @@
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
}
}
}

View file

@ -7,10 +7,11 @@
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
"platform": "neva.stl",
"platform_offset": [ 0, 0, 0],
"platform": "dagoma_neva.stl",
"platform_offset": [0, -28, -35],
"has_machine_quality": true,
"has_materials": true,
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_neva_extruder_0"
@ -69,6 +70,9 @@
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
}
}
}

View 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]]
]
}
}
}

View 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
}
}
}

View file

@ -44,7 +44,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1
"value": "1"
},
"top_bottom_thickness": {
"default_value": 1

View file

@ -75,7 +75,7 @@
"material_guid":
{
"label": "Material GUID",
"description": "GUID of the material. This is set automatically. ",
"description": "GUID of the material. This is set automatically.",
"default_value": "",
"type": "str",
"enabled": false
@ -142,6 +142,8 @@
"description": "The width (X-direction) of the printable area.",
"default_value": 100,
"type": "float",
"minimum_value": "0.001",
"maximum_value": "2000000",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@ -152,6 +154,8 @@
"description": "The depth (Y-direction) of the printable area.",
"default_value": 100,
"type": "float",
"minimum_value": "0.001",
"maximum_value": "2000000",
"settable_per_mesh": false,
"settable_per_extruder": 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.",
"unit": "mm",
"default_value": 0.8,
"value": "wall_line_width_0 if magic_spiralize else 0.8",
"minimum_value": "0",
"minimum_value_warning": "line_width",
"maximum_value_warning": "10 * line_width",
@ -1981,6 +1986,7 @@
"default_value": 1,
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"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",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true,
@ -1994,6 +2000,7 @@
"type": "float",
"default_value": 1,
"value": "skin_preshrink",
"maximum_value_warning": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"minimum_value": "0",
"enabled": "top_layers > 0 or bottom_layers > 0",
"limit_to_extruder": "top_bottom_extruder_nr",
@ -2007,6 +2014,7 @@
"type": "float",
"default_value": 1,
"value": "skin_preshrink",
"maximum_value_warning": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"minimum_value": "0",
"enabled": "top_layers > 0 or bottom_layers > 0",
"limit_to_extruder": "top_bottom_extruder_nr",
@ -2095,7 +2103,7 @@
"minimum_value": "0",
"maximum_value": "machine_height",
"type": "float",
"value": "0",
"value": "0 if infill_sparse_density > 0 else 0",
"limit_to_extruder": "infill_extruder_nr",
"enabled": "infill_sparse_density > 0",
"settable_per_mesh": true,
@ -2444,7 +2452,7 @@
"material_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",
"default_value": 0.5,
"enabled": false
@ -2452,23 +2460,23 @@
"material_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",
"default_value": 60,
"enabled": false
},
"material_end_of_filament_purge_speed":
{
"label": "End Of Filament Purge Speed",
"description": "Material Station internal value",
"label": "End of Filament Purge Speed",
"description": "How fast to prime the material after replacing an empty spool with a fresh spool of the same material.",
"type": "float",
"default_value": 0.5,
"enabled": false
},
"material_end_of_filament_purge_length":
{
"label": "End Of Filament Purge Length",
"description": "Material Station internal value",
"label": "End of Filament Purge Length",
"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",
"default_value": 20,
"enabled": false
@ -2476,7 +2484,7 @@
"material_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",
"default_value": 300,
"enabled": false
@ -2484,7 +2492,7 @@
"material_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",
"default_value": 0.940860215,
"enabled": false
@ -3635,7 +3643,7 @@
"retraction_enable":
{
"label": "Enable Retraction",
"description": "Retract the filament when the nozzle is moving over a non-printed area. ",
"description": "Retract the filament when the nozzle is moving over a non-printed area.",
"type": "bool",
"default_value": true,
"settable_per_mesh": false,
@ -4431,7 +4439,7 @@
"support_xy_distance_overhang":
{
"label": "Minimum Support X/Y Distance",
"description": "Distance of the support structure from the overhang in the X/Y directions. ",
"description": "Distance of the support structure from the overhang in the X/Y directions.",
"unit": "mm",
"type": "float",
"minimum_value": "0",
@ -5875,7 +5883,7 @@
"label": "Mesh Fixes",
"type": "category",
"icon": "category_fixes",
"description": "category_fixes",
"description": "Make the meshes more suited for 3D printing.",
"children":
{
"meshfix_union_all":
@ -6001,7 +6009,7 @@
"label": "Special Modes",
"type": "category",
"icon": "category_blackmagic",
"description": "category_blackmagic",
"description": "Non-traditional ways to print your models.",
"children":
{
"print_sequence":
@ -6174,7 +6182,7 @@
"label": "Experimental",
"type": "category",
"icon": "category_experimental",
"description": "experimental!",
"description": "Features that haven't completely been fleshed out yet.",
"children":
{
"support_tree_enable":

View file

@ -26,7 +26,7 @@
"layer_height_0": { "default_value": 0.2 },
"infill_sparse_density": { "default_value": 20 },
"wall_thickness": { "default_value": 1 },
"wall_thickness": { "value": "1" },
"top_bottom_thickness": { "default_value": 1 },
"machine_width": { "default_value": 240 },

View file

@ -25,7 +25,7 @@
"layer_height": { "default_value": 0.2 },
"layer_height_0": { "default_value": 0.3 },
"infill_sparse_density": { "default_value": 20 },
"wall_thickness": { "default_value": 1 },
"wall_thickness": { "value": "1" },
"top_bottom_thickness": { "default_value": 1 },
"infill_pattern": { "value": "'tetrahedral'" },

View 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 }
}
}

View 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" }
}
}

View file

@ -45,7 +45,7 @@
"machine_max_jerk_e": { "default_value": 2.5 },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"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": {
"default_value": "G91\nG1 E-1\nG0 X0 Y200\nM104 S0\nG90\nG92 E0\nM140 S0\nM84\nM104 S0\nM140 S0\nM84"

View file

@ -45,7 +45,7 @@
"machine_max_jerk_e": { "default_value": 2.5 },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"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": {
"default_value": "G91\nG1 E-1\nG0 X0 Y200\nM104 S0\nG90\nG92 E0\nM140 S0\nM84\nM104 S0\nM140 S0\nM84"

View file

@ -48,7 +48,7 @@
"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_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 }
}
}

View file

@ -46,7 +46,7 @@
"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_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 }
}
}

View file

@ -28,7 +28,7 @@
"machine_center_is_zero": { "default_value": false },
"layer_height": { "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 },
"infill_sparse_density": { "default_value": 20 },
"speed_print": { "default_value": 60 },

View file

@ -56,7 +56,7 @@
"default_value": 0.15
},
"wall_thickness": {
"default_value": 0.8
"value": "0.8"
},
"top_bottom_thickness": {
"default_value": 1.2

View file

@ -51,7 +51,7 @@
"default_value": 0.12
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"speed_print": {
"default_value": 40

View file

@ -51,7 +51,7 @@
"default_value": 0.12
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"speed_print": {
"default_value": 35

View file

@ -53,7 +53,7 @@
"default_value": 0.12
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"speed_print": {
"default_value": 40

View file

@ -51,7 +51,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"speed_print": {
"default_value": 60

View file

@ -51,7 +51,7 @@
"default_value": 0.2
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"speed_print": {
"default_value": 60

View file

@ -81,7 +81,7 @@
"default_value": 60
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"cool_min_layer_time_fan_speed_max": {
"default_value": 5

View file

@ -81,7 +81,7 @@
"default_value": 60
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"cool_min_layer_time_fan_speed_max": {
"default_value": 5

View file

@ -81,7 +81,7 @@
"default_value": 60
},
"wall_thickness": {
"default_value": 1.2
"value": "1.2"
},
"cool_min_layer_time_fan_speed_max": {
"default_value": 5

View file

@ -39,7 +39,7 @@
},
"layer_height": { "default_value": 0.2 },
"wall_thickness": { "default_value": 0.8 },
"wall_thickness": { "value": "0.8" },
"top_bottom_thickness": { "default_value": 0.3 },
"retraction_enable": { "default_value": true },
"retraction_speed": { "default_value": 50 },

View 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 }
}
}

View 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 }
}
}

View 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"
}
}
}

View 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"
}
}
}

View file

@ -189,7 +189,7 @@
"value": "machine_nozzle_size / 3"
},
"wall_thickness": {
"value": 0.5
"value": "0.5"
},
"infill_sparse_density": {
"value": 70

View file

@ -1,44 +1,33 @@
{
"name": "Rigid3D",
"name": "Rigid3D 2. Nesil",
"version": 2,
"inherits": "fdmprinter",
"inherits": "rigid3d_base",
"metadata": {
"visible": true,
"author": "Ultimaker",
"manufacturer": "Rigid3D",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
"machine_extruder_trains":
{
"0": "rigid3d_extruder_0"
}
},
"visible": true,
"quality_definition": "rigid3d_base",
"preferred_quality_type": "standard"
},
"overrides": {
"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_name": { "default_value": "Rigid3D 2. Nesil" },
"machine_heated_bed": { "default_value": true },
"machine_width": { "default_value": 250 },
"machine_depth": { "default_value": 250 },
"machine_width": { "default_value": 250 },
"machine_name": { "default_value": "Rigid3D" }
"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]
]
},
"gantry_height": { "value": 20 }
}
}

View file

@ -1,43 +1,33 @@
{
"name": "Rigid3D 3rdGen",
"name": "Rigid3D 3. Nesil",
"version": 2,
"inherits": "fdmprinter",
"inherits": "rigid3d_base",
"metadata": {
"visible": true,
"author": "Ultimaker",
"manufacturer": "Rigid3D",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
"machine_extruder_trains":
{
"0": "rigid3d_3rdgen_extruder_0"
}
},
"visible": true,
"quality_definition": "rigid3d_base",
"preferred_quality_type": "standard"
},
"overrides": {
"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_name": { "default_value": "Rigid3D 3. Nesil" },
"machine_heated_bed": { "default_value": true },
"machine_width": { "default_value": 270 },
"machine_depth": { "default_value": 290 },
"machine_width": { "default_value": 275 },
"machine_name": { "default_value": "Rigid3D 3rd Geneartion" }
"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]
]
},
"gantry_height": { "value": 20 }
}
}

View 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}
}
}

View file

@ -1,40 +1,159 @@
{
"name": "Rigid3D Hobby",
"version": 2,
"inherits": "fdmprinter",
"inherits": "rigid3d_base",
"metadata": {
"visible": true,
"author": "Ultimaker",
"manufacturer": "Rigid3D",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
"machine_extruder_trains":
{
"0": "rigid3d_hobby_extruder_0"
}
},
"visible": true,
"quality_definition": "rigid3d_base",
"preferred_quality_type": "standard",
"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_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_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_name": { "default_value": "Rigid3D Hobby" },
"machine_heated_bed": { "default_value": false },
"machine_width": { "default_value": 150 },
"machine_depth": { "default_value": 150 },
"machine_width": { "default_value": 150 },
"machine_name": { "default_value": "Rigid3D Hobby" }
"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]
]
},
"gantry_height": { "value": 20 }
}
}

View file

@ -1,142 +1,161 @@
{
"name": "Rigid3D Mucit",
"version": 2,
"inherits": "fdmprinter",
"inherits": "rigid3d_base",
"metadata": {
"visible": true,
"author": "Rigid3D",
"manufacturer": "Rigid3D",
"has_materials": false,
"file_formats": "text/x-gcode",
"platform": "rigid3d_mucit_platform.stl",
"visible": true,
"quality_definition": "rigid3d_base",
"preferred_quality_type": "standard",
"platform": "rigid3d_mucit_platform.stl",
"platform_offset": [ 0, -19, 0],
"preferred_quality_type": "draft",
"machine_extruder_trains":
{
"0": "rigid3d_mucit_extruder_0"
}
"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_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 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
},
"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"
}
"gantry_height": { "value": 20 }
}
}

View file

@ -1,44 +1,159 @@
{
"name": "Rigid3D Zero",
"version": 2,
"inherits": "fdmprinter",
"inherits": "rigid3d_base",
"metadata": {
"visible": true,
"author": "Ultimaker",
"manufacturer": "Rigid3D",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
"machine_extruder_trains":
{
"0": "rigid3d_zero_extruder_0"
}
},
"visible": true,
"quality_definition": "rigid3d_base",
"preferred_quality_type": "standard",
"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_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_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_name": { "default_value": "Rigid3D Zero" },
"machine_heated_bed": { "default_value": false },
"machine_width": { "default_value": 250 },
"machine_depth": { "default_value": 250 },
"machine_width": { "default_value": 250 },
"machine_name": { "default_value": "Rigid3D Zero" }
"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]
]
},
"gantry_height": { "value": 20 }
}
}

Some files were not shown because too many files have changed in this diff Show more