Skip to content

SDK Versions

Remco Burema edited this page Oct 9, 2024 · 10 revisions

Cura offers an SDK for plugins to interact with the software. Previously, plugins called a variety of Python methods exposed in Cura. From now on, we want to move functionality to an SDK layer that is more stable to use between Cura releases. Internally, this layer is known as Cura.API.

SDK Versioning

Each Cura release can have changes in its API, and this will be accompanied by a change in the SDK version. In the Change log section below, you can find all SDK versions and the corresponding Cura release versions.

Since Cura 4.0, the SDK version starting using semantic versioning, i.e. a number like 1.2.3. Below is a few examples showing which SDK versions of a plugin is considered compatible with a Cura SDK version:

Suppose Cura has SDK version 6.5.0.

  • Only plugins that support SDK versions 6.5.x is compatible because it's a patch version and it should not contain API-breaking changes.
  • SDK versions such as 6.7.x and 6.8.x are not compatible with 6.5.0 because they have minor version changes that can introduce new features. Those new features will not be present in 6.5.0.
  • SDK versions such as 6.1.0 and 6.4.0 are compatible because 6.5.0 contains all features in those versions.
  • SDK versions such as 5.x.y and 7.a.b are not compatible because their different major version numbers suggest breaking changes in the API.

Supporting multiple SDK's

It is possible for a plugin to support multiple SDK versions. First and foremost, the supported_sdk_versions property in the plugin.json file needs to be set. All versions that are supported can be placed in a list for this property.

When supporting multiple SDK's with a single plugin, it's fairly likely that different instances of plugin objects need to be provided, depending on the SDK version of Cura. The best way to do this is to make use of the register(app) function in the __init__ of the plugin. By checking at this point what the SDK version of the app is, different results can be returned. An example of this (although it provides different objects based on the operating system, the concept is the same) can be found in the RemovableDriveOutputDevice plugin.

Getting started

To use the API in your plug-in, simply get the API object from CuraApplication:

# The application instance is often already passed into the main class of your plugin.
def __init__(application: "CuraApplication") -> None:
    self._api = application.getCuraAPI()

# or

# Otherwise, just call getInstance() on the CuraApplication class to get it.
from cura.CuraApplication import CuraApplication
api = CuraApplication.getInstance().getCuraAPI()

# or

# As a final resort, you can also create a new instance of CuraAPI yourself, but this is deprecated.
from cura.API import CuraAPI
api = CuraAPI()

Now you can use the public properties on api.

Functionality

Change log

Cura 3.5.0 (SDK 5)

  • The official Cura API class is made available to make upgrading between versions more stable.

Cura 3.5.1 (SDK 5)

  • No SDK changes in this release.

Cura 3.6 (SDK 5)

  • The Ultimaker Account functionality was added to the SDK. Developers can use the API class in Cura to interact with this functionality. No SDK version change was done as the SDK version is not yet semantic (but will be from the next release onward) and the new functionality is only used by a single plugin from Ultimaker.

Cura 4.0 (SDK 6.0.0)

  • The UI has gotten a major overhaul, all plugins doing something with the UI (QML) should be updated.
  • The settings 'Minimum support area' and 'minimum support interface' have been added.
  • Output devices can now specify which type of output they are (USB, networking, butt).
  • New login functionality with an Ultimaker Account was added.

Cura 4.1 (SDK 6.1.0)

  • In order to connect Cura to printers, plug-ins can use the DiscoveredPrintersModel. The plug-in finds a bunch of printers, the user can select a printer and then the plug-in can register the printer in Cura and make it active.
  • The flow when first time users run Ultimaker Cura has changed. Now it shows a wizard-like dialog showing some pages one after the other. If a plug-in wants to make use of it, the best option is to create a model based on the WelcomePagesModel (as an example, take a look at AddPrinterPagesModel).

Cura 4.2 (SDK 6.2.0)

  • Orthogonal view has been added and plug-ins can display things differently depending on this view.
  • There is now a list model for all the objects on the build plate: ObjectsModel.
  • New settings were added to control the flow of different parts of the prints, such as infill, walls, skin, and so on. The print profiles can now make use of these settings.

Cura 4.3 (SDK 6.3.0)

  • Some modifications have been made to be able to select a single triangle in a model. (Used for instance in the 'lay flat by face' option.)
  • Architectural changes to allow display information about peripherals in the printer output device.

Cura 4.4 (SDK 7.0.0)

  • Major refactor to the Container system, which had to result in API rework to facilitate the Intent profiles. (For a lot of actions, instead of ...Manager, please now use ContainerTree.)

Cura 4.5 (SDK 7.1.0)

New additions:

  • SentryLogger plug-in
  • CuraApplication.installPackageViaDragAndDrop(file_url)
  • CuraApplication.getInstance() to return the correct type
  • AuthorizationRequestServer.setState(state)
  • LocalAuthorizationServer.start(verification_code, state)
  • ConvexHullDecorator.getPrintingArea()
  • ExtruderManager.getInitialExtruderNr()
  • MachineManager.getAllSettingKeys()
  • ImageReaderUI.onColorModelChanged(value)
  • ImageReaderUI.onTransmittanceChanged(value)
  • SimulationView.recalculateStartEndElements()
  • New classes in Toolbox: CloudApiModel, CloudPackageChecker, CloudPackageManager, DiscrepanciesPresenter, DownloadPresenter, LicenseModel, LicensePresenter, RestartApplicationPresenter, SubscribedPackagesModel, SyncOrchestrator, UltimakerCloudScope
  • Toolbox.launch()
  • Toolbox.onLicenseAccepted()
  • Toolbox.onLicenseDeclined()
  • Toolbox.setViewCategoryToMaterials()
  • Toolbox.getWebMarketplaceUrl(page)
  • VersionUpgrade44to45 plug-in
  • class XmlMaterialProfile.PluginInfo
  • Application.getAppFolderPrefix()
  • Controller.setCameraPosition(x_position, y_position, z_position)
  • Controller.setLookAtPosition(x_look_at_position, y_look_at_position, z_look_at_position)
  • Controller.setCameraZoomFactor(camera_zoom_factor)
  • Logger.debug(message)
  • Logger.info(message)
  • Logger.warning(message)
  • Logger.error(message)
  • Logger.critical(message)
  • MeshData.getFaceNodes(face_id)
  • Signal PackageManager.packageInstalled
  • PackageManager.getUserInstalledPackages()
  • PackageManager.dismissAllIncompatiblePackages(incompatible_packages)
  • PackageManager.getDismissedPackages()
  • PackageManager.reEvaluateDismissedPackages(subscribed_packages_payload, sdk_version)
  • PackageManager.removeFromDismissedPackages(package)
  • PluginRegistry.setCheckIfTrusted(check_if_trusted)
  • PluginRegistry.getCheckIfTrusted()
  • ControllerProxy.setCameraPosition(x_position, y_position, z_position)
  • ControllerProxy.setLookAtPosition(x_look_at_position, y_look_at_position, z_look_at_position)
  • ControllerProxy.setCameraZoomFactor(camera_zoom_factor)
  • QtApplication.resetWorkspace()
  • QtApplication.getHttpRequestManager()
  • QtApplication.applicationDisplayName()
  • QtRenderer.reRenderLast()
  • Camera.getInverseWorldTransformation()
  • Camera.getCameraLightPosition()
  • ContainerRegistry.setExplicitReadOnly(container_id)
  • ContainerRegistry.isExplicitReadOnly(container_id)
  • ContainerRegistryInterface.setExplicitReadOnly(container_id)
  • ContainerRegistryInterface.isExplicitReadOnly(container_id)
  • SettingDefinitionsModel.collapseRecursive(key)
  • SettingDefinitionsModel.collapseAllCategories()
  • SettingDefinitionsModel.onExpandedChanged()
  • Classes HttpRequestData, HttpRequestManager, HttpRequestScope, TaskManager

Cura 4.6 (SDK 7.2.0)

  • The setting_version is now at 14.
  • Class Trust
  • Enum OpenGLContext.OpenGlVersionDetect
  • OpenGLContext.detectBestOpenGLVersion(force_compatibility)
  • Class WorkspaceMetadataStorage

Cura 4.7 (SDK 7.3.0)

  • The setting_version is now at 15.
  • The new ConnectionStatus class shows whether the user has a connection with the internet. Request it via HttpRequestManager.isInternetReachable.
  • A new FastConfigParser class is a version of Python's configparser.ConfigParser with better performance, but fewer features.
  • Tool handles can now register extra widgets with their own colour.
  • SettingDefinition is now hashable, so it can be used in a set or as key of a dict.
  • SettingDefinition.matchesFilter now also looks through setting descriptions.
  • The Account class now has a number of functions to synchronize with the account information online.
  • A new SyncState QML element shows an icon and a message with the synchronization state with the account.
  • The new DiscoveredCloudPrintersModel shows a list of the printers the user can reach on his account.
  • The QtRenderer class now has a function addRenderBatch and tracks named render batches through getNamedBatch.
  • CuraSceneNode now has a function isSupportMesh to know whether the model is a support mesh.
  • SceneNode now has a function getCachedNormalMatrix that gets the normalized transformation matrix from cache.
  • ExtruderManager.registerExtruder is removed as it was dysfunct. Directly add it to the machine instance instead.
  • SettingOverrideDecorator now has functions like isCuttingMesh to detect the mesh type.
  • ObjectsModel now contains roles for extruder number, number of per-object settings and the mesh type.
  • UltimakerCloudAuthentication was renamed to UltimakerCloudConstants and contains the URL for the Digital Factory.
  • MeshBuilder has a function resetNormals that erases the mesh's own normals, causing it to reconstruct the normals from the vertices.
  • The Trust class has a function removeCached that clears __pycache__ folders before validating keys.
  • The VersionUpgrade parent class has a function getCfgVersion that uses a fixed convention to get version numbers from a CFG file.
  • A new QML widget TertiaryButton is a less salient button than the SecondaryButton.
  • A new QML widget ScrollView is a stylized scrollview in Cura's style.
  • A new QML widget AddCloudPrintersView shows a form where users can add cloud printers from their account.
  • A new setting "Scene Has Support Meshes" indicates whether there are any support meshes in the scene.
  • A new setting "Always Write Active Tool" indicates whether the firmware changes tools when a T parameter is encountered in heating commands.
  • A new setting "Support Structure" allows choosing between normal and tree support. It replaces "Enable Tree Support".
  • A new setting "Support Stair Step Minimum Slope" prevents stair-stepping on very shallow slopes.
  • Spaghetti Infill was removed.
  • Printer build plate meshes can now use 3MF and other multi-mesh formats.
  • A new printer "Smoothieware" is added to serve as basis for printers with Smoothieware firmware.

Cura 4.8 (SDK 7.4.0)

  • The setting version has been incremented to 16.
  • A new Nest2dArrange class is added that arranges objects more efficiently.
  • The Arrange class has been deprecated. Use Nest2dArrange instead.
  • BuildVolume has new functions to get its current width, height and depth.
  • CuraContainerStack now has a specialised function getProperty that gets the settable_per_extruder property properly.
  • MachineManager has a new signal that triggers when the number of custom setting overrides changes.
  • Polygon.approximatedCircle now accepts a parameter as to how many segments the approximated circle should have.
  • Polygon has a new function scale that applies a linear scale.
  • PluginRegistry.setCheckIfTrusted has a new parameter that allows using symlinks when running from source, but not while plug-in signatures are checked.
  • Trust has a new function setFollowSymlinks that allows you to configure that it needs to follow symlinks when running from source.

Cura 4.9 (SDK 7.5.0)

  • Cura now runs on CPython 3.8.8, bringing support for Python 3.8.
  • Cura's interface now runs on Qt 5.15.2, which brings new GUI functionality.
  • Cura now comes with OpenSSL 1.1.1, bringing support for newer types of SSL connections.
  • Cura's Ultimaker Account log-in token now has access to the Ultimaker Digital Library.
  • A new plug-in type is added, File Provider, which is intended to denote sources of where Cura can open model or project files from. These plug-ins are listed in the "File -> Open" menu.
  • The file providers can be listed with UM.Application.Application.getFileProviders.
  • Setting Visibility Preset files now have a version number, so that they can be upgraded. Files without version number will be seen as version 1 (and thus upgraded when starting 4.9 or later for the first time).
  • Added support for storing things on the keyrings of MacOS and Windows through the KeyringAttribute class. Linux is not supported.
  • The What's New pages can now have subpages, each with an image and a text.
  • The simulation view has new methods getShowStarts and setShowStarts to enable or disable the showing of extrusion starting points.
  • A new QML element was added: TableView. This is a themed version of QML's own TableView.
  • The Matrix class has a new function pseudoinvert which does a Moore-Penrose pseudoinvert.
  • A new operation type was added for the undo stack, the GravityOperation which moves the model down to Z=0.
  • A new class ProjectOutputDevice represents locations where Cura can store project files, which are made accessible through the "File -> Save" menu.
  • The DeviceManager class now has functions getProjectOutputDevices, addProjectOutputDevice and removeProjectOutputDevice to add project output devices.
  • The WorkspaceFileHandler class now has a setEnabled and an enabled function, to be able to disable them temporarily.
  • The WorkspaceMetadataStorage class has an easier to use function getPluginMetadataEntry to get a specific metadata entry instead of all of the metadata at once.

Cura 4.10.0 (SDK 7.6.0)

new classes & their methods

  • Uranium/UM/CentralFileStorage : This class stores and retrieves items (files or directories) stored in a location central to all versions of the application. Its purpose is to provide a way for plug-ins to store very big items (files or directories) without having those big items copied to the new resource directory at every version upgrade.
    • [classmethod] def store(cls, path: str, path_id: str, version: Version = Version("1.0.0"), move_file: bool = True) -> None Store a new item (file or directory) into the central file storage. This item will get moved to a storage location that is not specific to this version of the application.
    • [classmethod] def retrieve(cls, path_id: str, sha256_hash: str, version: Version = Version("1.0.0")) -> str Retrieve the path of a previously stored item (file or directory).
    • [classmethod] def setIsEnterprise(cls, is_enterprise: bool) -> None Some things central storage does will only (not) need to happen for enterprise editions of Cura. As of writing, this is only used to do a security check against the hash-values of the files.

added method signatures

  • in Uranium/UM/FileHandler/FileHandler: resolveAnySymlink(file_name: str) -> str Some linked files (.lnk in Windows for example) aren't always automatically resolved to their base. This method resolves to what they're pointing at, given the link filename.
  • in Uranium/UM/Trust/Trust: [classmethod] TrustBasics.getCentralStorageFilename(cls) -> str See 'CentralFileStorage' in 'new classes and methods'.
  • in Cura/Machines/Models/MaterialManagementModel: [pyqtProperty] MaterialManagementModel.preferredExportAllPath(self) -> QUrl Get the preferred path to export materials to.
  • in Cura/Machines/Models/MaterialManagementModel: [pyqtSlot] MaterialManagementModel.exportAll(self, file_path: QUrl) -> None Export all materials to a certain file path.
  • in Cura/Settings/GlobalStack: [pyqtProperty] GlobalStack.supportsMaterialExport(self) Whether the printer supports Cura's export format of material profiles.

added optional parameters and/or typechecking

  • in Uranium/UM/Bindings/Theme: Added 'detail_level' to Theme.getIcon [getIcon(self, icon_name: str, detail_level: str = "default") -> QUrl] ‘detail_level’: The level of detail of the icon. Choice between "low, "default", "medium", "high".
  • in Uranium/UM/View/GL/ShaderProgram: Added typechecking to ShaderProgram.setUniformValue [setUniformValue(self, name: str, value: Union[Vector, Matrix, Color, List[float], List[List[float]], float, int], **kwargs: Any) -> None]

Cura 4.12.0 (SDK 7.8.0)

  • The settings_version has been incremented to 19, up from 17 (skipping over 18, which was used in Arachne).
  • New replacement keys for start/end g-code: material_id, material_type, material_name and material_brand.
  • The sqlite Python module is now available on all platforms.
  • Added a preference to clear the build plate when loading a new object if the single-instance preference is enabled.
  • ProjectOutputDevice now has a getLastOutputName and setLastOutputName function, to store the last filename that was saved.
  • Added PackageManager.getPackagesInstalledOnStartup.
  • Added DatabaseContainerMetadataController, a fast database of profile metadata. We plan to transition the ContainerRegistry to use this for queries in the future.
  • Added DefinitionContainerUnpickler, a secure way to cache definition profiles.
  • Added SQLQueryFactory class, which can generate SQL queries.
  • IntentDatabaseHandler, QualityDatabaseHandler and VariantDatabaseHandler are an easy way to access certain types of profiles quickly.
  • The new additionalRights function the Account class gives a list of permissions the user has on the Ultimaker account.
  • The ExtrudersModel now also has a role for the material name.
  • Added an ApplicationSwitcher QML element, with a custom button and pop-up.

Cura 4.13.0 (SDK 7.9.0)

  • A new userProfileChanged signal indicates when the account information is updated.
  • Cura now gets permission to send materials to printers when logging in, making that available in Ultimaker's API.
  • The GlobalStacksModel now has a role to store whether printers are online (turned on and connected) or not.
  • The GlobalStacksModel can now be filtered by connection type, capabilities or being online.
  • The getUserProfile function is now asynchronous, returning the user profile via a callback instead of directly.
  • A new UploadMaterialsJob class will upload material profiles to the Digital Factory.
  • ExtruderManager now has a function getExtruderHasQualityForMaterial to check if there are profiles for a variant+material combination.

Cura 5.0.0 (SDK 8.0.0)

To get Mouse-Handling to work properly in Qt 6.2, we added the following methods and classes:

UM/Qt/Bindings/MainWindow:

  • def mousePressed(self, event):
  • def mouseMoved(self, event):
  • def wheel(self, event):
  • def mouseReleased(self, event):

UM/Qt/Bindings/MainWindow/MouseEventPosition:

  • class MouseEventPosition:
  • def x(self):
  • def y(self):

UM/Qt/Bindings/MainWindow/MouseEventWrapper:

  • class MouseEventWrapper:
  • def button(self):
  • def buttons(self):
  • def type(self):
  • def pos(self):
  • def angleDelta(self):

We largely aimed to keep at least our current UI, but Qt 6.2 necessitated the following changes due to some components no longer being supported w.r.t. Qt 5.x:

UM/ColorImage:

  • class ColorImage(QQuickPaintedItem):
  • def setSource(self, source: QUrl) -> None:
  • def source(self) -> QUrl:
  • def setColor(self, color: QColor) -> None:
  • def color(self) -> QColor:
  • def paint(self, painter: QPainter) -> None:

UM/Qt/Bindings/TableModel:

  • class TableModel(QAbstractTableModel):
  • def data(self, index: QModelIndex, _: int = ...) -> Any:
  • def rowCount(self, parent: QModelIndex = ...) -> int:
  • def columnCount(self, parent: QModelIndex = ...) -> int:
  • def rows(self):
  • def rows(self, rows: List[Dict[str, Any]]):
  • def headers(self):
  • def headers(self, headers: List[str]):
  • def clear(self) -> None:

We've finally begun removing deprecated methods. The following previously deprecated methods (and even some classes) are gone: in UM/Job:

  • def getMessage(self):
  • def setMessage(self, message) -> None:

in UM/Settings/SettingDefinitionModel:

  • def collapse(self, key: str) -> None:

in UM/Scene:

  • def getSceneLock(self) -> threading.Lock:

in Cura/CuraApplication:

  • def arrangeObjectsToAllBuildPlates(self) -> None:

in Cura/Arranging/*:

  • class Arrange:
  • class ArrangeArray:
  • class ArrangeObjectsAllBuildPlatesJob(Job):

in Cura/Settings/GlobalStack:

  • def extruders(self) -> Dict[str, "ExtruderStack"]:

Other (not previously deprecated) removed methods are:

UM/Theme:

  • def styles(self):

UM/Stage:

  • def iconSource(self) -> QUrl:
  • def setIconSource(self, source: Union[str, QUrl]) -> None:

Deleted UM/Math/ShapelyUtil:

  • def polygon2ShapelyPolygon(polygon: "Polygon") -> shapely.geometry.Polygon:

Some types have had to change (these are mostly in changed method signatures):

  • Changed relevant Dict[str, Any] to PackageData (= MutableMapping[str, Any]) where applicable.
  • Changed relevant Dict[str, Dict[str, Any]] to PackageDataDict (= MutableMapping[str, PackageData]) where applicable.
  • Changed ast.Index to ast.Subscript

The following methods have had their signature changed or expanded:

UM/Qt/ListModel: changed:

  • def sort(self, fun: Callable[[Any], float]) -> None:

to include optional arguments:

  • def sort(self, fun: Callable[[Any], float], key: Optional[str] = None, reverse = False) -> None:

UM/Qt/QtApplication: renamed:

  • def exec_(self, *args: Any, **kwargs: Any) -> None:

to (note the lack of underscore):

  • def exec(self, *args: Any, **kwargs: Any) -> None:

Lastly, the following methods where added wholesale:

UM/Qt/QtApplication:

  • def isQmlEngineInitialized(self) -> bool:

UM/Math/Matrix:

  • def getFlatData(self):

UM/PackageManager:

  • def reinstallPackage(self, package_id: str) -> bool:
  • def isBundledPackage(self, package_id: str) -> bool:
  • def getPackagesToInstall(self) -> PackageDataDict:
  • def hasPackagesToRemoveOrInstall(self) -> bool:
  • def canDowngrade(self, package_id: str) -> bool:

UM/PluginRegistry:

  • def getCurrentSessionActivationChangedPlugins(self) -> Set[str]:

UM/Settings/SettingDefinition:

  • def toFloatConversion(value: str) -> float:
  • def toIntConversion(value):

UM/Signal:

  • def acquire_timeout(lock, timeout):

Cura/PackageManager:

  • def local_packages(self) -> List[Dict[str, Any]]:
  • def local_packages_ids(self) -> Set[str]:
  • def getAllLocalPackages(self) -> List[Dict[str, Any]]:

We changed a lot of Qt/QML, so regarding the changes there, we've chosen for a high-level overview of removed/added classes. (So, this is not an exhaustive list of all changes, just the added/removed QML components.) Depending on the type of plugin, you can also expect changes due to the underlying upgrade to Qt 6.2.

The following QML classes were removed:

  • UM/Qt/qml/UM/Preferences/SettingVisibilityCategory.qml
  • UM/Qt/qml/UM/Preferences/SettingVisibilityItem.qml
  • UM/Qt/qml/UM/RecolorImage.qml
  • UM/Qt/qml/UM/Wizard.qml
  • Cura/resources/qml/CheckBoxWithTooltip.qml
  • Cura/resources/qml/Menus/LocalPrinterMenu.qml
  • Cura/resources/qml/Menus/NetworkPrinterMenu.qml
  • Cura/resources/qml/Preferences/ProfileTab.qml
  • Cura/resources/qml/Preferences/ReadOnlySpinBox.qml
  • Cura/resources/qml/Preferences/ReadOnlyTextField.qml
  • Cura/resources/qml/ToolbarButton.qml
  • Cura/resources/qml/Widgets/CheckBox.qml
  • Cura/resources/themes/cura-light/styles.qml

The following QML classes were added:

  • UM/Qt/qml/UM/BurgerButton.qml
  • UM/Qt/qml/UM/CheckBox.qml
  • UM/Qt/qml/UM/Enums.qml
  • UM/Qt/qml/UM/ImageButton.qml
  • UM/Qt/qml/UM/Label.qml
  • UM/Qt/qml/UM/Menu.qml
  • UM/Qt/qml/UM/MenuItem.qml
  • UM/Qt/qml/UM/MessageDialog.qml
  • UM/Qt/qml/UM/ScrollBar.qml
  • UM/Qt/qml/UM/TextFieldWithUnit.qml
  • UM/Qt/qml/UM/ToolTip.qml
  • UM/Qt/qml/UM/ToolbarButton.qml
  • UM/Qt/qml/UM/UnderlineBackground.qml
  • Cura/resources/qml/CategoryButton.qml
  • Cura/resources/qml/ColorDialog.qml
  • Cura/resources/qml/Dialogs/MessageDialog.qml
  • Cura/resources/qml/Menus/EditMenu.qml
  • Cura/resources/qml/Menus/ExtensionMenu.qml
  • Cura/resources/qml/Menus/HelpMenu.qml
  • Cura/resources/qml/Menus/MaterialBrandMenu.qml
  • Cura/resources/qml/Menus/PreferencesMenu.qml
  • Cura/resources/qml/Preferences/RenameDialog.qml
  • Cura/resources/qml/Preferences/SettingVisibilityCategory.qml
  • Cura/resources/qml/Preferences/SettingVisibilityItem.qml
  • Cura/resources/qml/PrintSetupHeaderButton.qml
  • Cura/resources/qml/ProfileOverview.qml
  • Cura/resources/qml/SearchBar.qml
  • Cura/resources/qml/SpinBox.qml

External packages

  • Qt5 is no longer supported, and you need to use Qt6
  • Python 3.10 features is now supported
  • Shapely is replaced with Pyclipper

Cura 5.1.0 (SDK 8.1.0)

  • Added IntentSelectionModel for QML to show which intents are available.
  • Added ActiveIntentQualitiesModel for QML to show which quality profiles are available given the current intent.
  • Added acceleration_travel_enabled and jerk_travel_enabled settings.
  • Added a ProfileWarningReset QML element which shows the status of customisation: User changes and/or a custom profile, and allows resetting them.
  • Added a RecommendedQualityProfileSelectorButton QML element which allows selecting intent profiles (not quality profiles!)
  • Added a RecommendedResolutionSelector QML element which displays a drop-down to change the quality level.
  • CuraPackageManager has a new function getMaterialFilePackageId to know which package a material profile belongs to.
  • CuraPackageManager has a new function isMaterialBundled to know whether a material file is bundled.
  • Added intentCategoryHasQuality to the MachineManager.
  • Added getDefaultQualityTypeForIntent to the MachineManager.
  • The Theme object now has the setCheckIfTrusted function, by which you can indicate whether a theme comes from a trusted source (for Cura editions that don't allow untrusted resources) or not.
  • You can now add secure resource paths to the Resources class with addSecureSearchPath and getSecureSearchPaths, which makes Cura trust a new resource path (for Cura editions that don't allow untrusted resources).
  • Added OpenGL::getOpenGLVersionShort, which gives an easier-to-parse version number of the active OpenGL instance.

Cura 5.2.0 (SDK 8.2.0)

Python Files Added:

  • cura/Machines/Models/CompatibleMachineModel.py

Python Functions Added:

  • cura/API/Account.py:

    • permissionsChanged = pyqtSignal()
    • def permissions(self) -> List[str]:
  • cura/Machines/Models/GlobalStacksModel.py:

    • def setFilterAbstractMachines(self, new_filter: Optional[bool]) -> None:
    • def filterAbstractMachines(self) -> Optional[bool]:
  • cura/PrinterOutput/Models/PrintJobOutputModel.py:

    • def isMine(self) -> bool:
  • cura/Settings/CuraStackBuilder.py:

    • def createUserContainer(cls, new_stack_id: str, definition: DefinitionContainerInterface,stack: GlobalStack, variant_container: "InstanceContainer", material_container: "InstanceContainer", quality_container: "InstanceContainer"):
    • def createAbstractMachine(cls, definition_id: str) -> Optional[GlobalStack]:
  • cura/Settings/GlobalStack.py:

    • def hasNetworkedConnection(self) -> bool:
  • cura/Settings/MachineManager.py:

    • def getMachinesWithDefinition(self, definition_id: str, online_only=False) -> List[ContainerStack]:
    • def activeMachineIsAbstractCloudPrinter(self) -> bool:
  • UM/Settings/InstanceContainer.py

    • def createMergedInstanceContainer(cls, instance_container1: "InstanceContainer",instance_container2: "InstanceContainer") -> "InstanceContainer":

Python Functions Deprecated:

  • cura/API/Account.py "Get permissions from the 'permissions' property" def updateAdditionalRight(self, **kwargs) -> None:
  • cura/API/Account.py "Get permissions from the 'permissions' property" def additionalRights(self) -> Dict[str, Any]:
  • UM/Qt/QtApplication.py "Showing toast messages is no longer supported" def showToastMessage(self, title: str, message: str) -> None:

QML Components Added:

  • cura/resources/qml/Dialogs/ChoosePrinterDialog.qml
  • cura/resources/qml/PrinterSelector/MachineListButton.qml
  • cura/resources/qml/PrinterSelector/PrintSelectorCard.qml
  • cura/resources/qml/Menus/Configurationmenu/CustomConfiguration.qml

QML Components Removed:

  • printerTypeSelectorRow and all sub-items

QML Properties Changed:

  • cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml
    • Added property ignoreValueChange to infillSlider item

Cura 5.3.0 (SDK 8.3.0)

Python Files Added:

  • cura/Settings/ActiveQuality.py

Python Functions Added:

  • cura/Machines/Models/MachineListModel.py:
    • set_machines_filter(self, machines_filter: Optional[List[GlobalStack]]) -> None
  • cura/Settings/ExtruderManager.py:
    • emitGlobalStackExtrudersChanged(self):
  • cura/Settings/MachineManager.py:
    • activeQualityDisplayNameMap(self) -> ActiveQuality
  • cura/CuraApplication.py:
    • showCompareAndSaveProfileChanges = pyqtSignal(int)
  • cura/MachineAction.py:
    • visibilityChanged = pyqtSignal()

QML Components Added:

  • UM/validators/FloatValidator
  • UM/validators/HexColorValidator
  • UM/validators/IntListValidator
  • UM/validators/IntValidator
  • UM/ComponentWithIcon
  • UM/Slider
  • UM/Switch
  • UM/TextField

QML Components Removed:

  • UM/TextFieldWithUnit

QML Properties Changed:

  • cura/Settings/ExtruderManager.py:
    • Added property enabledExtruderCount to ExtruderManager
  • cura/Settings/MachineManager.py:
    • Added property activeQualityDisplayNameMainStringPart to MachineManager
    • Added property activeQualityDisplayNameTailStringParts to MachineManager
  • cura/MachineAction.py:
    • Added property shouldOpenAsDialog to MachineAction
    • Added property visible to MachineAction

Cura 5.4.x (SDK 8.4.0)

Changes in Python

  • in cura/Settings/CuraFormulaFunctions.py
    • def getAnyExtruderPositionWithOrDefault(self, filter_key: str, context: Optional["PropertyEvaluationContext"] = None) -> str Returns the first extruder that has the (boolean) 'filter_key' property set to true, and if no such extruders exist, returns the default extruder position (as with getDefaultExtruderPosition). This function can be used in settings-formulas as 'anyExtruderNrWithOrDefault(...)'. warning: In its present implementation, this settings-function might slow down the UI if used in often evaluated places within a (printer-)definition.

Changes in QML

  • in PrintSetupCollectorRecommended/RecommendedQualityProfileSelectorButton.qml

    • New property custom_icon: Use in order to give profile-authors (materials, etc.) the option of supplying a bespoke icon with their custom Intents.
  • in WelcomePages/AddLocalPrinterScrollView.qml

    • Property currentSections is now a var instead of a string.
    • Function updateCurrentItemUponSectionChange(...) now has a parameter called 'section'.

Cura 5.5.x (SDK 8.5.x)

Cura

Python

Deprecated 3 'static' function-overloads in Nest2DArrange file (use similar non-static functions in Nest2DArrange class instead)

  • 'static' def findNodePlacement
  • 'static' def createGroupOperationForArrange
  • 'static' def arrange

new class BackendPlugin

new class Arranger (now a superclass of Nest2DArrange)

new class GridArrange

in class BuildVolume

  • def getShape(self) -> str

in class CuraActions

  • def multiplySelectionToGrid(self, count: int) -> None
  • def cut(self) -> None
  • def copy(self) -> None
  • def paste(self) -> None

in class CuraApplication

  • def arrangeAllInGrid(self) -> None

[added parameters to]

  • def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], *, grid_arrangement: bool = False) -> None

  • def getBackendPlugins(self) -> List["BackendPlugin"]

in class MultiplyObjectsJob

[added parameters to]

  • def __init__(self, objects, count: int, min_offset: int = 8 ,* , grid_arrange: bool = False)

in class CuraContainerStack

['upgraded' to non-private class-method]

  • def findInstanceContainerDefinitionId(cls, machine_definition: DefinitionContainerInterface) -> str

in class CuraFormulaFunctions

  • def getExtruderPositionWithMaterial(self, filter_key: str, context: Optional["PropertyEvaluationContext"] = None) -> str

Qml

Deprecated Cura.ColorDialog workaround (use Qml ColorDialog)

in Actions.qml, ContextMenu.qml, etc.

  • Added paste, copy and cut actions
  • Added openSponsershipPageActions
  • Added clamp function to SpinBox.qml
  • Added forceUpdate function to SingleSettingComboBox.qml

Uranium

Python

new class AdditionalSettingDefinitionAppender

in class PackageManager.py

  • def allEnabledPackages(self) -> List[str]

Qml

Added ScrollableTextArea

Cura 5.6.x (SDK 8.6.x)

Cura

Python functions added

  • cura/Snapshot.py
    • def isometricSnapshot(width: int = 300, height: int = 300) -> Optional[QImage]
    • def nodeBounds(root_node: SceneNode) -> Optional[AxisAlignedBox]

Uranium

Python functions changed

  • UM/Settings/SettingFunction.py
    • Add additional_variables argument to def __call__(self, value_provider: ContainerInterface, context: Optional[PropertyEvaluationContext] = None, *, additional_variables: Optional[Dict[str, Any]] = None) -> Any

Python functions added

  • UM/Math/AxisAlignedBox.py
    • def points(self) -> Tuple[Vector, Vector, Vector, Vector, Vector, Vector, Vector, Vector]

Qml functions added

  • UM/Qt/qml/UM/Menu.qml
    • function adjustWidth()

Cura 5.7.x (SDK 8.7.x)

Cura

Python functions added
  • Class CuraActions
    • def canUndo(self)
    • def canRedo(self)
    • def undo(self)
    • def redo(self)
  • class CuraApplication
    • def setWorkplaceDropToBuildplate(self)
    • def getSupportedActionMachineList(self, definition_id)
    • def exportUcp(self)
    • def readLocalUcpFile(self, file, add_to_recent_files)
    • def isProjectUcp(self, file_url)
  • class LayerPolygon
    • def lineLengths(self)
  • class PlatformPhysics
    • def setAppAllModelDropDown(self)
  • class MachineListModel
    • def getItems(self)
  • class NetworkedPrinterOutputDevice
    • @staticmethod def applyPrinterTypeMapping(printer_type)
  • class ExtruderConfigurationModel
    • def applyNameMappingHotend(hotendId)
  • class MaterialOutputModel
    • @staticmethod def getMaterialFromDefinition(guid, type, brand, name)
  • class CuraSceneNode
    • def printOrder(self)
    • def printOrder(self, new_value)
    • def isDropDownEnabled(self)
  • class ObjectsModel
    • def getNodes(self)
Python functions changed
  • class PreviewPass
    • Add arguments * and root to def __init__(self, width, height, *, root)
  • class SingleInstance
    • Add argument url_to_open to def __init__(self, application, files_to_open, url_to_open)
  • class Snapshot
    • Add arguments * and root to def isometricSnapshot(width, height, *, node)
  • class MachineListModel
    • Add argument showCloudPrinters to def __init__(self, parent, machines_filter, listenToChanges, showCloudPrinters)
  • class AuthorizationService
    • Add argument get_user_profile to def __init__(self, settings, preferences, get_user_profile)
  • class BackendPlugin.py
    • Add argument catalog_i18n to def __init__(self, catalog_i18n)
Qml items added
  • AskOpenAsProjectOrUcpOrImportModel.qml

Uranium

Python functions added
  • class QtApplication
    • def version(self)
  • class ControllerProxy
    • def valid(self)
    • def activeToolPanel(self)
    • def triggerAction(self, action)
    • def triggerActionWithData(self, action, data)
    • def properties(self)
    • def forceUpdate(self)
    • def setProperty(self, property, value)
  • class HttpRequestManager
    • def setDelayRequests(self, delay_requests)
  • class SelectionPass
    • def getIdAtPositionFaceMode(self, x, y)
Python functions changed
  • class HttpRequestManager
    • Add argument urgent to def get(self, url, headers_dict, callback, error_callback, download_progress_callback, upload_progress_callback, timeout, scope, urgent)
    • Add argument urgent to def put(self, url, headers_dict, data, callback, error_callback, download_progress_callback, upload_progress_callback, timeout, scope, urgent)
    • Add argument urgent to def post(self, url, headers_dict, data, callback, error_callback, download_progress_callback, upload_progress_callback, timeout, scope, urgent)
    • Add argument urgent to def delete(self, url, headers_dict, callback, error_callback, download_progress_callback, upload_progress_callback, timeout, scope, urgent
Python functions deprecated
  • class ActiveToolProxy
  • class ApplicationProxy
  • class Bindings
    • def createApplicationProxy(self, engine, script_engine)
    • def createOperationStackProxy(cls, engine, script_engine)
  • class OperationStackProxy
Qml items added
  • HelpIcon.qml

Cura 5.8.x (SDK 8.8.x)

Cura

Qml functions removed (not previously deprecated)
  • AddLocalPrinterScrollView.qml
    • function getMachineName()
    • function getMachineMetaDataEntry(key)
Qml functions added
  • AddLocalPrinterScrollView.qml
    • function updateCurrentItem(index)
Qml items changed
  • AddLocalPrinterScrollView.qml
    • Global rework of the inner elements

Cura 5.9.x (SDK 8.9.x)

new functionality

  • in UM/Decorators.py
+ class CachedMemberFunctions
+   @classmethod def clearInstanceCache(cls, instance)
+   @classmethod def deleteInstanceCache(cls, instance)
+   @classmethod def callMemberFunction(cls, instance, function, *args, **kwargs)
+ def cache_per_instance(function)
+ def cache_per_instance_copy_result(function)

The new cache_per_instance and cache_per_instance_copy_result decorators cache the result of member-functions. Copying the result will give a shallow copy, so that the returned information isn't purged when the cache is. Speaking of purging the cache (on a per-instance basis of course), that can be handled with clearInstanceCache (or even deleteInstanceCache).

  • in UM/Settings/SettingDefinition
+ def relationsAsFrozenSet(self) -> frozenset["SettingRelation"]
  • in cura/PrinterOutput/FormatMaps.py
+ class FormatMaps
+   PRINTER_TYPE_NAME
+   EXTRUDER_NAME_MAP
+   MATERIAL_MAP
+   @classmethod def getInversePrinterNameMap(cls) -> Dict[str, str]
+   @classmethod def getInverseExtruderTypeMap(cls) -> Dict[str, str]
+   @classmethod def getInverseMaterialMap(cls) -> Dict[str, str]
+   @classmethod def getProductIdMap(cls) -> Dict[str, List[str]]
  • in cura/Machines/MachineNode.py
+ def isExcludedMaterialBaseFile(self, material_base_file: str) -> bool
  • in cura/API/Interface/Settings.py
+ def getSliceMetadata(self) -> Dict[str, Dict[str, Dict[str, str]]]

deprecated

  • in cura/Machines/MachineNode.py
~ @deprecated("Use isExcludedMaterialBaseFile instead.", since = "5.9.0")
~ def isExcludedMaterial(self, material: MaterialNode) -> bool:

expanded signatures

  • in UM/FileHandler/WriteFileJob.py
- def __init__(self, writer: Optional[FileWriter], stream: Union[io.BytesIO, io.StringIO], data: Any, mode: int) -> None
+ def __init__(self, writer: Optional[FileWriter], stream: Union[io.BytesIO, io.StringIO], data: Any, mode: int, writer_args: Optional[Dict[str, Any]] = None) -> None
  • in UM/Workspace/WorkspaceWriter.py
- def write(self, stream, node, mode = FileWriter.OutputMode.BinaryMode)
+ def write(self, stream, node, mode = FileWriter.OutputMode.BinaryMode, **kwargs)
  • in UM/Settings/InstanceContainer.py
- def setName(self, name: str) -> None
+ def setName(self, name: str, *, supress_signals = False) -> None

Feature requests

Do you want to stably use functionality but there is no API for it yet? Feel free to submit a pull request or talk to one of the developers via the GitHub issues board about getting it supported. To get started, have a look at the current API implementation.

Clone this wiki locally