def _getPropertyValue(self, property_name):
        # Use the evaluation context to skip certain containers
        context = PropertyEvaluationContext(self._stack)
        context.context["evaluate_from_container_index"] = self._store_index

        property_value = self._stack.getProperty(self._key, property_name, context = context)
        if isinstance(property_value, SettingFunction):
            property_value = property_value(self._stack)

        if property_name == "value":
            setting_type = self._stack.getProperty(self._key, "type")
            if setting_type is not None:
                property_value = SettingDefinition.settingValueToString(setting_type, property_value)
            else:
                property_value = ""
        elif property_name == "validationState":
            # Setting is not validated. This can happen if there is only a setting definition.
            # We do need to validate it, because a setting defintions value can be set by a function, which could
            # be an invalid setting.
            if property_value is None:
                if not self._validator:
                    definition = self._stack.getSettingDefinition(self._key)
                    if definition:
                        validator_type = SettingDefinition.getValidatorForType(definition.type)
                        if validator_type:
                            self._validator = validator_type(self._key)
                if self._validator:
                    property_value = self._validator(self._stack)
        return str(property_value)
def benchmark_findDefinitions(benchmark, filter, match_count):
    definition = SettingDefinition("test", None)
    definition.deserialize({
        "label": "Test",
        "type": "int",
        "default_value": 10,
        "description": "Test Setting",
        "children": {
            "test_child_1": {
                "label": "Test Child 1",
                "type": "int",
                "default_value": 20,
                "description": "Test Child Setting 1"
            },
            "test_child_2": {
                "label": "Test Child 2",
                "type": "int",
                "default_value": 20,
                "description": "Test Child Setting 2"
            }
        }
    })

    result = benchmark(definition.findDefinitions, **filter)
    assert len(result) == match_count
def _createSettingDefinition(properties):
    result = SettingDefinition(properties["key"]) # Key MUST be present.
    if "default_value" in properties:
        result._SettingDefinition__property_values["default_value"] = properties["default_value"] # Nota bene: Setting a private value depends on implementation, but changing a property is not currently exposed.
    result._SettingDefinition__property_values["description"] = "Test setting definition"
    result._SettingDefinition__property_values["type"] = "str"
    if "children" in properties:
        for child in properties["children"]:
            result.children.append(_createSettingDefinition(child))
    return result
    def __init__(self, parent = None, *args, **kwargs):
        super().__init__(parent = parent, *args, **kwargs)

        self._container_id = None
        self._container = None
        self._i18n_catalog = None

        self._root_key = ""
        self._root = None

        self._definition_list = []
        self._row_index_list = []

        self._expanded = set()
        self._visible = set()
        self._exclude = set()

        self._show_all = False
        self._show_ancestors = False
        self._visibility_handler = None

        self._filter_dict = {}

        self._role_names = {
            self.KeyRole: b"key",
            self.DepthRole: b"depth",
            self.VisibleRole: b"visible",
            self.ExpandedRole: b"expanded",
        }
        index = self.ExpandedRole + 1
        for name in SettingDefinition.getPropertyNames():
            self._role_names[index] = name.encode()
            index += 1
Example #5
0
    def deserialize(self, serialized):
        # update the serialized data first
        serialized = super().deserialize(serialized)
        parsed = self._readAndValidateSerialized(serialized)

        # Update properties with the data from the JSON
        self._name = parsed["name"]
        self._metadata = parsed["metadata"]

        for key, value in parsed["settings"].items():
            definition = SettingDefinition(key, self, None, self._i18n_catalog)
            definition.deserialize(value)
            self._definitions.append(definition)

        for definition in self._definitions:
            self._updateRelations(definition)
Example #6
0
    def __init__(self, parent = None, *args, **kwargs):
        super().__init__(parent = parent, *args, **kwargs)

        self._container_id = None
        self._container = None

        self._role_names = {
            self.KeyRole: b"key"
        }
        index = self.KeyRole + 1
        for name in SettingDefinition.getPropertyNames():
            self._role_names[index] = name.encode()
            index += 1
Example #7
0
    def deserialize(self, serialized: str, file_name: Optional[str] = None) -> str:
        # update the serialized data first
        serialized = super().deserialize(serialized, file_name)
        parsed, is_valid = self.readAndValidateSerialized(serialized)

        # Update properties with the data from the JSON
        old_id = self.getId() #The ID must be set via the constructor. Retain it.
        self._metadata = parsed["metadata"]
        self._metadata["id"] = old_id
        self._metadata["name"] = parsed["name"]
        self._metadata["version"] = self.Version #Guaranteed to be equal to what's in the parsed data by the validation.
        self._metadata["container_type"] = DefinitionContainer

        for key, value in parsed["settings"].items():
            definition = SettingDefinition(key, self, None, self._i18n_catalog)
            definition.deserialize(value)
            self._definitions.append(definition)

        for definition in self._definitions:
            self._updateRelations(definition)

        return serialized
Example #8
0
 def getErrorKeys(self) -> List[str]:
     error_keys = []
     for key in self.getAllKeys():
         validation_state = self.getProperty(key, "validationState")
         if validation_state is None:
             # Setting is not validated. This can happen if there is only a setting definition.
             # We do need to validate it, because a setting defintions value can be set by a function, which could
             # be an invalid setting.
             definition = cast(SettingDefinition, self.getSettingDefinition(key))
             validator_type = SettingDefinition.getValidatorForType(definition.type)
             if validator_type:
                 validator = validator_type(key)
                 validation_state = validator(self)
         if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
             error_keys.append(key)
     return error_keys
    def _getPropertyValue(self, property_name: str) -> str:
        property_value = self._container.getProperty(self._key, property_name)
        if isinstance(property_value, SettingFunction):
            property_value = property_value(self._container)

        if property_name == "value":
            setting_type = self._container.getProperty(self._key, "type")
            if not setting_type:
                instance = self._container.getInstance(self._key)
                if instance:
                    setting_type = instance.definition.type

            if setting_type:
                property_value = SettingDefinition.settingValueToString(setting_type, property_value)

        return str(property_value)
Example #10
0
 def hasErrors(self) -> bool:
     for key in self.getAllKeys():
         enabled = self.getProperty(key, "enabled")
         if not enabled:
             continue
         validation_state = self.getProperty(key, "validationState")
         if validation_state is None:
             # Setting is not validated. This can happen if there is only a setting definition.
             # We do need to validate it, because a setting defintions value can be set by a function, which could
             # be an invalid setting.
             definition = cast(SettingDefinition, self.getSettingDefinition(key))
             validator_type = SettingDefinition.getValidatorForType(definition.type)
             if validator_type:
                 validator = validator_type(key)
                 validation_state = validator(self)
         if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
             return True
     return False
Example #11
0
 def hasErrors(self) -> bool:
     for key in self.getAllKeys():
         enabled = self.getProperty(key, "enabled")
         if not enabled:
             continue
         validation_state = self.getProperty(key, "validationState")
         if validation_state is None:
             # Setting is not validated. This can happen if there is only a setting definition.
             # We do need to validate it, because a setting defintions value can be set by a function, which could
             # be an invalid setting.
             definition = self.getSettingDefinition(key)
             validator_type = SettingDefinition.getValidatorForType(
                 definition.type)
             if validator_type:
                 validator = validator_type(key)
                 validation_state = validator(self)
         if validation_state in (ValidatorState.Exception,
                                 ValidatorState.MaximumError,
                                 ValidatorState.MinimumError):
             return True
     return False
    def __init__(self, parent = None, *args, **kwargs):
        super().__init__(parent = parent)

        self._container_id = None  # type: Optional[str]
        self._container = None  # type: Optional[DefinitionContainerInterface]
        self._i18n_catalog = None

        self._root_key = ""  # type: str
        self._root = None  # type: Optional[SettingDefinition]

        self._definition_list = []  # type: List[SettingDefinition]
        self._row_index_list = []  # type: List[int]

        self._expanded = set()  # type: Set[str]
        self._visible = set()  # type: Set[str]
        self._exclude = set()  # type: Set[str]

        self._show_all = False  # type: bool
        self._show_ancestors = False  # type: bool
        self._visibility_handler = None  # type: Optional[SettingPreferenceVisibilityHandler]

        self._update_visible_row_scheduled = False  # type: bool
        self._destroyed = False  # type: bool

        self._filter_dict = {}  # type: Dict[str, str]

        self._role_names = {
            self.KeyRole: b"key",
            self.DepthRole: b"depth",
            self.VisibleRole: b"visible",
            self.ExpandedRole: b"expanded",
        }  # type: Dict[int, bytes]
        index = self.ExpandedRole + 1
        for name in SettingDefinition.getPropertyNames():
            self._role_names[index] = name.encode()
            index += 1

        self.destroyed.connect(self._onDestroyed)

        self.expandedChanged.connect(self.onExpandedChanged)
Example #13
0
    def _checkStack(self):
        if self._need_to_check:
            Logger.log("d", "Need to check for errors again. Discard the current progress and reschedule a check.")
            self._check_in_progress = False
            self._application.callLater(self.startErrorCheck)
            return

        self._check_in_progress = True

        # If there is nothing to check any more, it means there is no error.
        if not self._stacks_and_keys_to_check:
            # Finish
            self._setResult(False)
            return

        # Get the next stack and key to check
        stack, key = self._stacks_and_keys_to_check.popleft()

        enabled = stack.getProperty(key, "enabled")
        if not enabled:
            self._application.callLater(self._checkStack)
            return

        validation_state = stack.getProperty(key, "validationState")
        if validation_state is None:
            # Setting is not validated. This can happen if there is only a setting definition.
            # We do need to validate it, because a setting definitions value can be set by a function, which could
            # be an invalid setting.
            definition = stack.getSettingDefinition(key)
            validator_type = SettingDefinition.getValidatorForType(definition.type)
            if validator_type:
                validator = validator_type(key)
                validation_state = validator(stack)
        if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
            # Finish
            self._setResult(True)
            return

        # Schedule the check for the next key
        self._application.callLater(self._checkStack)
Example #14
0
    def _checkStack(self) -> None:
        if self._need_to_check:
            Logger.log("d", "Need to check for errors again. Discard the current progress and reschedule a check.")
            self._check_in_progress = False
            self._application.callLater(self.startErrorCheck)
            return

        self._check_in_progress = True

        # If there is nothing to check any more, it means there is no error.
        if not self._stacks_and_keys_to_check:
            # Finish
            self._setResult(False)
            return

        # Get the next stack and key to check
        stack, key = self._stacks_and_keys_to_check.popleft()

        enabled = stack.getProperty(key, "enabled")
        if not enabled:
            self._application.callLater(self._checkStack)
            return

        validation_state = stack.getProperty(key, "validationState")
        if validation_state is None:
            # Setting is not validated. This can happen if there is only a setting definition.
            # We do need to validate it, because a setting definitions value can be set by a function, which could
            # be an invalid setting.
            definition = stack.getSettingDefinition(key)
            validator_type = SettingDefinition.getValidatorForType(definition.type)
            if validator_type:
                validator = validator_type(key)
                validation_state = validator(stack)
        if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
            # Finish
            self._setResult(True)
            return

        # Schedule the check for the next key
        self._application.callLater(self._checkStack)
Example #15
0
    def _checkStackForErrors(self, stack: ContainerStack) -> bool:

        top_of_stack = cast(InstanceContainer,
                            stack.getTop())  # Cache for efficiency.
        changed_setting_keys = top_of_stack.getAllKeys()

        # Add all relations to changed settings as well.
        for key in top_of_stack.getAllKeys():
            instance = top_of_stack.getInstance(key)
            if instance is None:
                continue
            self._addRelations(changed_setting_keys,
                               instance.definition.relations)
            Job.yieldThread()

        for changed_setting_key in changed_setting_keys:
            validation_state = stack.getProperty(changed_setting_key,
                                                 "validationState")

            if validation_state is None:
                definition = cast(
                    SettingDefinition,
                    stack.getSettingDefinition(changed_setting_key))
                validator_type = SettingDefinition.getValidatorForType(
                    definition.type)
                if validator_type:
                    validator = validator_type(changed_setting_key)
                    validation_state = validator(stack)
            if validation_state in (ValidatorState.Exception,
                                    ValidatorState.MaximumError,
                                    ValidatorState.MinimumError,
                                    ValidatorState.Invalid):
                Logger.log(
                    "w", "Setting %s is not valid, but %s. Aborting slicing.",
                    changed_setting_key, validation_state)
                return True
            Job.yieldThread()

        return False
    def __init__(self, parent=None, *args, **kwargs):
        super().__init__(parent=parent, *args, **kwargs)

        self._container_id = None
        self._container = None
        self._i18n_catalog = None

        self._root_key = ""
        self._root = None

        self._definition_list = []
        self._row_index_list = []

        self._expanded = set()
        self._visible = set()
        self._exclude = set()

        self._show_all = False  # type: bool
        self._show_ancestors = False  # type: bool
        self._visibility_handler = None

        self._update_visible_row_scheduled = False  # type: bool
        self._destroyed = False  # type: bool

        self._filter_dict = {}

        self._role_names = {
            self.KeyRole: b"key",
            self.DepthRole: b"depth",
            self.VisibleRole: b"visible",
            self.ExpandedRole: b"expanded",
        }
        index = self.ExpandedRole + 1
        for name in SettingDefinition.getPropertyNames():
            self._role_names[index] = name.encode()
            index += 1

        self.destroyed.connect(self._onDestroyed)
Example #17
0
    def getErrorKeys(self) -> List[str]:
        """Get all the keys that are in an error state in this stack"""

        error_keys = []
        for key in self.getAllKeys():
            validation_state = self.getProperty(key, "validationState")
            if validation_state is None:
                # Setting is not validated. This can happen if there is only a setting definition.
                # We do need to validate it, because a setting defintions value can be set by a function, which could
                # be an invalid setting.
                definition = cast(SettingDefinition,
                                  self.getSettingDefinition(key))
                validator_type = SettingDefinition.getValidatorForType(
                    definition.type)
                if validator_type:
                    validator = validator_type(key)
                    validation_state = validator(self)
            if validation_state in (ValidatorState.Exception,
                                    ValidatorState.MaximumError,
                                    ValidatorState.MinimumError,
                                    ValidatorState.Invalid):
                error_keys.append(key)
        return error_keys
def test_valueChanges(container_registry):
    setting_property_provider = SettingPropertyProvider()

    # First create the basics; A container stack that will hold 2 instance containers and a single definition container
    container_stack = ContainerStack("test!")
    instance_container = InstanceContainer("data")
    second_instance_container = InstanceContainer("data2")
    definition_container = DefinitionContainer("foo")

    # Create a setting definition for our one and only setting!
    setting_definition = SettingDefinition("test_setting")
    setting_definition._deserialize_dict({"value": 10, "label": "blorp", "type": "float", "description": "nah", "maximum_value": 23, "maximum_value_warning": 21, "enabled": "test_setting != 20"})
    definition_container.addDefinition(setting_definition)

    # Make a single setting instance for our one and only setting.
    setting_instance = SettingInstance(setting_definition, instance_container)
    setting_instance.setProperty("value", 20)
    setting_instance.setProperty("enabled", False)
    instance_container.addInstance(setting_instance)

    # Make a setting instance that lives in our second instance_container
    setting_instance2 = SettingInstance(setting_definition, second_instance_container)
    second_instance_container.addInstance(setting_instance2)

    # Now that both containers are done, actually add them.
    container_stack.addContainer(definition_container)
    container_stack.addContainer(second_instance_container)
    container_stack.addContainer(instance_container)

    setting_property_provider.setContainerStack(container_stack)
    setting_property_provider.setKey("test_setting")
    assert setting_property_provider.key == "test_setting"

    assert setting_property_provider.getPropertyValue("value", 0) == 20

    setting_property_provider.setWatchedProperties(["enabled", "value", "validationState"])
    setting_property_provider._update()
    assert setting_property_provider.watchedProperties == ["enabled", "value", "validationState"]
    assert setting_property_provider.properties.value("enabled") == "False"
    assert setting_property_provider.properties.value("value") == "20"

    # Validator state is a special property that gets added based on the type and the value
    assert setting_property_provider.properties.value("validationState") == str(ValidatorState.Valid)

    # Set the property value to something that will trigger a warning
    setting_property_provider.setPropertyValue("value", 22)
    assert setting_property_provider.properties.value("validationState") == str(ValidatorState.MaximumWarning)
    assert setting_property_provider.getPropertyValue("value", 0) == 22
    # The setting doesn't exist in our second instance container, so this should be None
    assert setting_property_provider.getPropertyValue("value", 1) is None

    # Set the property value to something that will trigger an error
    setting_property_provider.setPropertyValue("value", 25)
    # The Qtimer that we use to prevent flooding doesn't work in tests, so tickle the change manually.
    setting_property_provider._update()

    assert setting_property_provider.properties.value("validationState") == str(ValidatorState.MaximumError)

    # We now ask for the second instance container to be targeted
    setting_property_provider.setStoreIndex(1)
    assert setting_property_provider.storeIndex == 1

    setting_property_provider.setPropertyValue("value", 2)
    setting_property_provider._update()
    # So now we should see a change in that instance container
    assert setting_property_provider.getPropertyValue("value", 1) == 2
    # But not if we ask the provider, because the container above it still has a 25 as value!
    assert setting_property_provider.getPropertyValue("value", 0) == 25

    assert setting_property_provider.stackLevels == [0, 1, 2]

    # We're asking for an index that doesn't exist.
    assert setting_property_provider.getPropertyValue("value", 2000) is None

    # The value is used, so the property must be true
    assert setting_property_provider.isValueUsed

    # Try to remove the setting from the container
    setting_property_provider.removeFromContainer(0)
    assert setting_property_provider.getPropertyValue("value", 0) is None

    # Ensure that a weird index doesn't break
    setting_property_provider.removeFromContainer(90001)
Example #19
0
    def __init__(self):
        Resources.addSearchPath(os.path.join(QtApplication.getInstallPrefix(), "share", "cura", "resources"))
        if not hasattr(sys, "frozen"):
            Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources"))

        self._open_file_queue = []  # Files to open when plug-ins are loaded.

        # Need to do this before ContainerRegistry tries to load the machines
        SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True, read_only = True)
        SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True, read_only = True)
        # this setting can be changed for each group in one-at-a-time mode
        SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True, read_only = True)
        SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True, read_only = True)

        # From which stack the setting would inherit if not defined per object (handled in the engine)
        # AND for settings which are not settable_per_mesh:
        # which extruder is the only extruder this setting is obtained from
        SettingDefinition.addSupportedProperty("limit_to_extruder", DefinitionPropertyType.Function, default = "-1")

        # For settings which are not settable_per_mesh and not settable_per_extruder:
        # A function which determines the glabel/meshgroup value by looking at the values of the setting in all (used) extruders
        SettingDefinition.addSupportedProperty("resolve", DefinitionPropertyType.Function, default = None, depends_on = "value")

        SettingDefinition.addSettingType("extruder", None, str, Validator)

        SettingFunction.registerOperator("extruderValues", cura.Settings.ExtruderManager.getExtruderValues)
        SettingFunction.registerOperator("extruderValue", cura.Settings.ExtruderManager.getExtruderValue)
        SettingFunction.registerOperator("resolveOrValue", cura.Settings.ExtruderManager.getResolveOrValue)

        ## Add the 4 types of profiles to storage.
        Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality")
        Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants")
        Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials")
        Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user")
        Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders")
        Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances")

        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack)

        ##  Initialise the version upgrade manager with Cura's storage paths.
        import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies.
        UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
            {
                ("quality", UM.Settings.InstanceContainer.Version):    (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
                ("machine_stack", UM.Settings.ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
                ("preferences", UM.Preferences.Version):               (Resources.Preferences, "application/x-uranium-preferences"),
                ("user", UM.Settings.InstanceContainer.Version):       (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer")
            }
        )

        self._machine_action_manager = MachineActionManager.MachineActionManager()
        self._machine_manager = None    # This is initialized on demand.
        self._setting_inheritance_manager = None

        self._additional_components = {} # Components to add to certain areas in the interface

        super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType)

        self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))

        self.setRequiredPlugins([
            "CuraEngineBackend",
            "MeshView",
            "LayerView",
            "STLReader",
            "SelectionTool",
            "CameraTool",
            "GCodeWriter",
            "LocalFileOutputDevice"
        ])
        self._physics = None
        self._volume = None
        self._output_devices = {}
        self._print_information = None
        self._previous_active_tool = None
        self._platform_activity = False
        self._scene_bounding_box = AxisAlignedBox.Null

        self._job_name = None
        self._center_after_select = False
        self._camera_animation = None
        self._cura_actions = None
        self._started = False

        self._message_box_callback = None
        self._message_box_callback_arguments = []

        self._i18n_catalog = i18nCatalog("cura")

        self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity)
        self.getController().toolOperationStopped.connect(self._onToolOperationStopped)

        Resources.addType(self.ResourceTypes.QmlFiles, "qml")
        Resources.addType(self.ResourceTypes.Firmware, "firmware")

        self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading machines..."))

        # Add empty variant, material and quality containers.
        # Since they are empty, they should never be serialized and instead just programmatically created.
        # We need them to simplify the switching between materials.
        empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
        empty_variant_container = copy.deepcopy(empty_container)
        empty_variant_container._id = "empty_variant"
        empty_variant_container.addMetaDataEntry("type", "variant")
        ContainerRegistry.getInstance().addContainer(empty_variant_container)
        empty_material_container = copy.deepcopy(empty_container)
        empty_material_container._id = "empty_material"
        empty_material_container.addMetaDataEntry("type", "material")
        ContainerRegistry.getInstance().addContainer(empty_material_container)
        empty_quality_container = copy.deepcopy(empty_container)
        empty_quality_container._id = "empty_quality"
        empty_quality_container.setName("Not supported")
        empty_quality_container.addMetaDataEntry("quality_type", "normal")
        empty_quality_container.addMetaDataEntry("type", "quality")
        ContainerRegistry.getInstance().addContainer(empty_quality_container)
        empty_quality_changes_container = copy.deepcopy(empty_container)
        empty_quality_changes_container._id = "empty_quality_changes"
        empty_quality_changes_container.addMetaDataEntry("type", "quality_changes")
        ContainerRegistry.getInstance().addContainer(empty_quality_changes_container)

        # Set the filename to create if cura is writing in the config dir.
        self._config_lock_filename = os.path.join(Resources.getConfigStoragePath(), CONFIG_LOCK_FILENAME)
        self.waitConfigLockFile()
        ContainerRegistry.getInstance().load()

        Preferences.getInstance().addPreference("cura/active_mode", "simple")
        Preferences.getInstance().addPreference("cura/recent_files", "")
        Preferences.getInstance().addPreference("cura/categories_expanded", "")
        Preferences.getInstance().addPreference("cura/jobname_prefix", True)
        Preferences.getInstance().addPreference("view/center_on_select", True)
        Preferences.getInstance().addPreference("mesh/scale_to_fit", True)
        Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True)

        for key in [
            "dialog_load_path",  # dialog_save_path is in LocalFileOutputDevicePlugin
            "dialog_profile_path",
            "dialog_material_path"]:

            Preferences.getInstance().addPreference("local_file/%s" % key, os.path.expanduser("~/"))

        Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode")

        Preferences.getInstance().setDefault("general/visible_settings", """
            machine_settings
            resolution
                layer_height
            shell
                wall_thickness
                top_bottom_thickness
            infill
                infill_sparse_density
            material
                material_print_temperature
                material_bed_temperature
                material_diameter
                material_flow
                retraction_enable
            speed
                speed_print
                speed_travel
                acceleration_print
                acceleration_travel
                jerk_print
                jerk_travel
            travel
            cooling
                cool_fan_enabled
            support
                support_enable
                support_extruder_nr
                support_type
                support_interface_density
            platform_adhesion
                adhesion_type
                adhesion_extruder_nr
                brim_width
                raft_airgap
                layer_0_z_overlap
                raft_surface_layers
            dual
                prime_tower_enable
                prime_tower_size
                prime_tower_position_x
                prime_tower_position_y
            meshfix
            blackmagic
                print_sequence
                infill_mesh
            experimental
        """.replace("\n", ";").replace(" ", ""))

        JobQueue.getInstance().jobFinished.connect(self._onJobFinished)

        self.applicationShuttingDown.connect(self.saveSettings)
        self.engineCreatedSignal.connect(self._onEngineCreated)
        self._recent_files = []
        files = Preferences.getInstance().getValue("cura/recent_files").split(";")
        for f in files:
            if not os.path.isfile(f):
                continue

            self._recent_files.append(QUrl.fromLocalFile(f))
Example #20
0
import sys
import json

from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
from UM.Settings.Validator import Validator
from UM.Settings.DefinitionContainer import DefinitionContainer

if len(sys.argv) < 3:
    print("Usage: query.py [file] [query]")
    exit(1)

file_path = sys.argv[1]

# These are defined by Cura but we would still like to be able to query them.
SettingDefinition.addSupportedProperty("settable_per_mesh",
                                       DefinitionPropertyType.Any,
                                       default=True,
                                       read_only=True)
SettingDefinition.addSupportedProperty("settable_per_extruder",
                                       DefinitionPropertyType.Any,
                                       default=True,
                                       read_only=True)
SettingDefinition.addSupportedProperty("settable_per_meshgroup",
                                       DefinitionPropertyType.Any,
                                       default=True,
                                       read_only=True)
SettingDefinition.addSupportedProperty("settable_globally",
                                       DefinitionPropertyType.Any,
                                       default=True,
                                       read_only=True)
SettingDefinition.addSupportedProperty("limit_to_extruder",
                                       DefinitionPropertyType.Function,
Example #21
0
    def __init__(self):
        Resources.addSearchPath(
            os.path.join(QtApplication.getInstallPrefix(), "share", "cura",
                         "resources"))
        if not hasattr(sys, "frozen"):
            Resources.addSearchPath(
                os.path.join(os.path.abspath(os.path.dirname(__file__)), "..",
                             "resources"))

        self._open_file_queue = []  # Files to open when plug-ins are loaded.

        # Need to do this before ContainerRegistry tries to load the machines
        SettingDefinition.addSupportedProperty("global_only",
                                               DefinitionPropertyType.Function,
                                               default=False)
        SettingDefinition.addSettingType("extruder", int, str,
                                         UM.Settings.Validator)

        super().__init__(name="cura",
                         version=CuraVersion,
                         buildtype=CuraBuildType)

        self.setWindowIcon(
            QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))

        self.setRequiredPlugins([
            "CuraEngineBackend", "MeshView", "LayerView", "STLReader",
            "SelectionTool", "CameraTool", "GCodeWriter",
            "LocalFileOutputDevice"
        ])
        self._physics = None
        self._volume = None
        self._platform = None
        self._output_devices = {}
        self._print_information = None
        self._i18n_catalog = None
        self._previous_active_tool = None
        self._platform_activity = False
        self._scene_bounding_box = AxisAlignedBox()
        self._job_name = None
        self._center_after_select = False
        self._camera_animation = None
        self._cura_actions = None
        self._started = False

        self.getController().getScene().sceneChanged.connect(
            self.updatePlatformActivity)
        self.getController().toolOperationStopped.connect(
            self._onToolOperationStopped)

        Resources.addType(self.ResourceTypes.QmlFiles, "qml")
        Resources.addType(self.ResourceTypes.Firmware, "firmware")

        ## Add the 4 types of profiles to storage.
        Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer,
                                 "quality")
        Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer,
                                 "variants")
        Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer,
                                 "materials")
        Resources.addStorageType(self.ResourceTypes.UserInstanceContainer,
                                 "user")
        Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders")
        Resources.addStorageType(self.ResourceTypes.MachineStack,
                                 "machine_instances")

        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.QualityInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.VariantInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.MaterialInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.UserInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.ExtruderStack)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.MachineStack)

        # Add empty variant, material and quality containers.
        # Since they are empty, they should never be serialized and instead just programmatically created.
        # We need them to simplify the switching between materials.
        empty_container = ContainerRegistry.getInstance(
        ).getEmptyInstanceContainer()
        empty_variant_container = copy.deepcopy(empty_container)
        empty_variant_container._id = "empty_variant"
        empty_variant_container.addMetaDataEntry("type", "variant")
        ContainerRegistry.getInstance().addContainer(empty_variant_container)
        empty_material_container = copy.deepcopy(empty_container)
        empty_material_container._id = "empty_material"
        empty_material_container.addMetaDataEntry("type", "material")
        ContainerRegistry.getInstance().addContainer(empty_material_container)
        empty_quality_container = copy.deepcopy(empty_container)
        empty_quality_container._id = "empty_quality"
        empty_quality_container.addMetaDataEntry("type", "quality")
        ContainerRegistry.getInstance().addContainer(empty_quality_container)

        ContainerRegistry.getInstance().load()

        Preferences.getInstance().addPreference("cura/active_mode", "simple")
        Preferences.getInstance().addPreference("cura/recent_files", "")
        Preferences.getInstance().addPreference("cura/categories_expanded", "")
        Preferences.getInstance().addPreference("cura/jobname_prefix", True)
        Preferences.getInstance().addPreference("view/center_on_select", True)
        Preferences.getInstance().addPreference("mesh/scale_to_fit", True)
        Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True)
        Preferences.getInstance().setDefault("local_file/last_used_type",
                                             "text/x-gcode")

        Preferences.getInstance().setDefault(
            "general/visible_settings", """
            machine_settings
                resolution
                layer_height
            shell
                wall_thickness
                top_bottom_thickness
            infill
                infill_sparse_density
            material
                material_print_temperature
                material_bed_temperature
                material_diameter
                material_flow
                retraction_enable
            speed
                speed_print
                speed_travel
            travel
            cooling
                cool_fan_enabled
            support
                support_enable
                support_type
                support_roof_density
            platform_adhesion
                adhesion_type
                brim_width
                raft_airgap
                layer_0_z_overlap
                raft_surface_layers
            meshfix
            blackmagic
                print_sequence
                dual
            experimental
        """.replace("\n", ";").replace(" ", ""))

        JobQueue.getInstance().jobFinished.connect(self._onJobFinished)

        self.applicationShuttingDown.connect(self.saveSettings)

        self._recent_files = []
        files = Preferences.getInstance().getValue("cura/recent_files").split(
            ";")
        for f in files:
            if not os.path.isfile(f):
                continue

            self._recent_files.append(QUrl.fromLocalFile(f))
def test_valueChanges(container_registry):
    setting_property_provider = SettingPropertyProvider()
    # First create the basics; A container stack that will hold 2 instance containers and a single definition container
    container_stack = ContainerStack("test!")
    instance_container = InstanceContainer("data")
    second_instance_container = InstanceContainer("data2")
    definition_container = DefinitionContainer("foo")

    # Create a setting definition for our one and only setting!
    setting_definition = SettingDefinition("test_setting")
    setting_definition._deserialize_dict({"value": 10, "label": "blorp", "type": "float", "description": "nah", "maximum_value": 23, "maximum_value_warning": 21})
    definition_container.addDefinition(setting_definition)

    # Make a single setting instance for our one and only setting.
    setting_instance = SettingInstance(setting_definition, instance_container)
    setting_instance.setProperty("value", 20)
    setting_instance.setProperty("enabled", False)
    instance_container.addInstance(setting_instance)

    # Make a setting instance that lives in our second instance_container
    setting_instance2 = SettingInstance(setting_definition, second_instance_container)
    second_instance_container.addInstance(setting_instance2)

    # Now that both containers are done, actually add them.
    container_stack.addContainer(definition_container)
    container_stack.addContainer(second_instance_container)
    container_stack.addContainer(instance_container)

    setting_property_provider.setContainerStack(container_stack)
    setting_property_provider.setKey("test_setting")

    assert setting_property_provider.getPropertyValue("value", 0) == 20

    setting_property_provider.setWatchedProperties(["enabled", "value", "validationState"])
    assert setting_property_provider.properties.value("enabled") == "False"
    assert setting_property_provider.properties.value("value") == "20"

    # Validator state is a special property that gets added based on the type and the value
    assert setting_property_provider.properties.value("validationState") == str(ValidatorState.Valid)

    # Set the property value to something that will trigger a warning
    setting_property_provider.setPropertyValue("value", 22)
    assert setting_property_provider.properties.value("validationState") == str(ValidatorState.MaximumWarning)
    assert setting_property_provider.getPropertyValue("value", 0) == 22
    # The setting doesn't exist in our second instance container, so this should be None
    assert setting_property_provider.getPropertyValue("value", 1) is None

    # Set the property value to something that will trigger an error
    setting_property_provider.setPropertyValue("value", 25)
    # The Qtimer that we use to prevent flooding doesn't work in tests, so tickle the change manually.
    setting_property_provider._update()

    assert setting_property_provider.properties.value("validationState") == str(ValidatorState.MaximumError)

    # We now ask for the second instance container to be targeted
    setting_property_provider.setStoreIndex(1)
    assert setting_property_provider.storeIndex == 1

    setting_property_provider.setPropertyValue("value", 2)
    setting_property_provider._update()
    # So now we should see a change in that instance container
    assert setting_property_provider.getPropertyValue("value", 1) == 2
    # But not if we ask the provider, because the container above it still has a 25 as value!
    assert setting_property_provider.getPropertyValue("value", 0) == 25

    assert setting_property_provider.stackLevels == [0, 1, 2]

    # We're asking for an index that doesn't exist.
    assert setting_property_provider.getPropertyValue("value", 2000) is None

    # The value is used, so the property must be true
    assert setting_property_provider.isValueUsed

    # Try to remove the setting from the container
    setting_property_provider.removeFromContainer(0)
    assert setting_property_provider.getPropertyValue("value", 0) is None

    # Ensure that a weird index doesn't break
    setting_property_provider.removeFromContainer(90001)
Example #23
0
    def _updateRelations(self, definition: SettingDefinition):
        for property in SettingDefinition.getPropertyNames(DefinitionPropertyType.Function):
            self._processFunction(definition, property)

        for child in definition.children:
            self._updateRelations(child)
Example #24
0
    def _onContainerLoadComplete(self, container_id):
        container = ContainerRegistry.getInstance().findContainers(
            id=container_id)[0]
        if not isinstance(container, DefinitionContainer):
            # skip containers that are not definitions
            return
        if container.getMetaDataEntry("type") == "extruder":
            # skip extruder definitions
            return

        material_settings_category = container.findDefinitions(key="material")
        klipper_settings_category = container.findDefinitions(
            key=self._category_key)
        if material_settings_category and not klipper_settings_category:
            # this machine doesn't have a GCODE Offset setting yet
            material_settings_category = material_settings_category[0]
            klipper_settings_category = SettingDefinition(
                self._category_key, container, None, self._i18n_catalog)

            category_dict = self._category_dict
            category_dict["children"] = OrderedDict()

            klipper_gcode_offset_definition = SettingDefinition(
                self._setting_k_g_offset_key, container,
                klipper_settings_category, self._i18n_catalog)
            klipper_gcode_offset_definition.deserialize(
                self._setting_k_g_offset_dict)

            klipper_pa_definition = SettingDefinition(
                self._setting_k_pa_key, container, klipper_settings_category,
                self._i18n_catalog)
            klipper_pa_definition.deserialize(self._setting_k_pa_dict)

            klipper_pa_l_definition = SettingDefinition(
                self._setting_k_pa_l_key, container, klipper_settings_category,
                self._i18n_catalog)
            klipper_pa_l_definition.deserialize(self._setting_k_pa_l_dict)

            category_dict["children"][
                self._setting_k_g_offset_key] = self._setting_k_g_offset_dict
            category_dict["children"][
                self._setting_k_pa_key] = self._setting_k_pa_dict
            category_dict["children"][
                self._setting_k_pa_l_key] = self._setting_k_pa_l_dict

            klipper_settings_category.deserialize(category_dict)
            container.addDefinition(klipper_settings_category)

            container._updateRelations(klipper_settings_category)
    def _onContainerLoadComplete(self, container_id):
        container = ContainerRegistry.getInstance().findContainers(
            id=container_id)[0]
        if not isinstance(container, DefinitionContainer):
            # skip containers that are not definitions
            return
        if container.getMetaDataEntry("type") == "extruder":
            # skip extruder definitions
            return

        material_category1 = container.findDefinitions(
            key="material")  # Pressure Advance
        material_category2 = container.findDefinitions(
            key="material")  # Pressure Advance Lookahead
        speed_category1 = container.findDefinitions(
            key="speed")  # square corner velocity
        speed_category4 = container.findDefinitions(
            key="speed")  # acceleration
        speed_category2 = container.findDefinitions(
            key="speed")  # acceleration to deceleration
        speed_category3 = container.findDefinitions(
            key="speed")  # acceleration order

        pressure_advance_setting = container.findDefinitions(
            key=self._setting_key_klipper_pressure_advance)
        pressure_advance_lookahead_setting = container.findDefinitions(
            key=self._setting_key_klipper_pressure_advance_lookahead)
        square_corner_velocity_setting = container.findDefinitions(
            key=self._setting_key_square_corner_velocity)
        acceleration_setting = container.findDefinitions(
            key=self._setting_key_klipper_acceleration)
        acceleration_to_deceleration_setting = container.findDefinitions(
            key=self._setting_key_klipper_acceleration_to_deceleration)
        acceleration_order_setting = container.findDefinitions(
            key=self._setting_key_klipper_acceleration_order)

        # Pressure Advance Lookahead
        if material_category2 and not pressure_advance_lookahead_setting:
            # this machine doesn't have a Pressure Advance setting yet
            material_category2 = material_category2[0]
            pressure_advance_lookahead_definition = SettingDefinition(
                self._setting_key_klipper_pressure_advance_lookahead,
                container, material_category2, self._i18n_catalog)
            pressure_advance_lookahead_definition.deserialize(
                self._setting_dict_klipper_pressure_advance_lookahead)

            # add the setting to the already existing PA setting definition
            # private member access is naughty, but the alternative is to serialise, nix and deserialise the whole thing,
            # which breaks stuff
            material_category2._children.append(
                pressure_advance_lookahead_definition)
            container._definition_cache[
                self.
                _setting_key_klipper_pressure_advance_lookahead] = pressure_advance_lookahead_definition
            container._updateRelations(pressure_advance_lookahead_definition)

        # Pressure Advance
        if material_category1 and not pressure_advance_setting:
            # this machine doesn't have a Pressure Advance setting yet
            material_category1 = material_category1[0]
            pressure_advance_definition = SettingDefinition(
                self._setting_key_klipper_pressure_advance, container,
                material_category1, self._i18n_catalog)
            pressure_advance_definition.deserialize(
                self._setting_dict_klipper_pressure_advance)

            # add the setting to the already existing PA setting definition
            # private member access is naughty, but the alternative is to serialise, nix and deserialise the whole thing,
            # which breaks stuff
            material_category1._children.append(pressure_advance_definition)
            container._definition_cache[
                self.
                _setting_key_klipper_pressure_advance] = pressure_advance_definition
            container._updateRelations(pressure_advance_definition)

        # Square Corner Velocity
        if speed_category1 and not square_corner_velocity_setting:
            # this machine doesn't have a Square Corner Velocity setting yet
            speed_category1 = speed_category1[0]
            square_corner_velocity_definition = SettingDefinition(
                self._setting_key_square_corner_velocity, container,
                speed_category1, self._i18n_catalog)
            square_corner_velocity_definition.deserialize(
                self._setting_dict_square_corner_velocity)

            # add the setting to the already existing speed settingdefinition
            # private member access is naughty, but the alternative is to serialise, nix and deserialise the whole thing,
            # which breaks stuff
            speed_category1._children.append(square_corner_velocity_definition)
            container._definition_cache[
                self.
                _setting_key_square_corner_velocity] = square_corner_velocity_definition
            container._updateRelations(square_corner_velocity_definition)

        # Acceleration
        if speed_category4 and not acceleration_setting:
            # this machine doesn't have a Acceleration setting yet
            speed_category4 = speed_category4[0]
            klipper_acceleration_definition = SettingDefinition(
                self._setting_key_klipper_acceleration, container,
                speed_category4, self._i18n_catalog)
            klipper_acceleration_definition.deserialize(
                self._setting_dict_klipper_acceleration)

            # add the setting to the already existing speed settingdefinition
            # private member access is naughty, but the alternative is to serialise, nix and deserialise the whole thing,
            # which breaks stuff
            speed_category4._children.append(klipper_acceleration_definition)
            container._definition_cache[
                self.
                _setting_key_klipper_acceleration] = klipper_acceleration_definition
            container._updateRelations(klipper_acceleration_definition)

        # Acceleration to Deceleration
        if speed_category2 and not acceleration_to_deceleration_setting:
            # this machine doesn't have a Acceleration to deceleration setting yet
            speed_category2 = speed_category2[0]
            klipper_acceleration_to_deceleration_definition = SettingDefinition(
                self._setting_key_klipper_acceleration_to_deceleration,
                container, speed_category2, self._i18n_catalog)
            klipper_acceleration_to_deceleration_definition.deserialize(
                self._setting_dict_klipper_acceleration_to_deceleration)

            # add the setting to the already existing speed settingdefinition
            # private member access is naughty, but the alternative is to serialise, nix and deserialise the whole thing,
            # which breaks stuff
            speed_category2._children.append(
                klipper_acceleration_to_deceleration_definition)
            container._definition_cache[
                self.
                _setting_key_klipper_acceleration_to_deceleration] = klipper_acceleration_to_deceleration_definition
            container._updateRelations(
                klipper_acceleration_to_deceleration_definition)

        # Acceleration Order
        if speed_category3 and not acceleration_order_setting:
            # this machine doesn't have a Acceleration to deceleration setting yet
            speed_category3 = speed_category3[0]
            klipper_acceleration_order_definition = SettingDefinition(
                self._setting_key_klipper_acceleration_order, container,
                speed_category3, self._i18n_catalog)
            klipper_acceleration_order_definition.deserialize(
                self._setting_dict_klipper_acceleration_order)

            # add the setting to the already existing speed settingdefinition
            # private member access is naughty, but the alternative is to serialise, nix and deserialise the whole thing,
            # which breaks stuff
            speed_category3._children.append(
                klipper_acceleration_order_definition)
            container._definition_cache[
                self.
                _setting_key_klipper_acceleration_order] = klipper_acceleration_order_definition
            container._updateRelations(klipper_acceleration_order_definition)
Example #26
0
    def _updateRelations(self, definition: SettingDefinition):
        for property in SettingDefinition.getPropertyNames(DefinitionPropertyType.Function):
            self._processFunction(definition, property)

        for child in definition.children:
            self._updateRelations(child)
Example #27
0
import os
import sys
import json

from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
from UM.Settings.Validator import Validator
from UM.Settings.DefinitionContainer import DefinitionContainer

if len(sys.argv) < 3:
    print("Usage: query.py [file] [query]")
    exit(1)

file_path = sys.argv[1]

# These are defined by Cura but we would still like to be able to query them.
SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True, read_only = True)
SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True, read_only = True)
SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True, read_only = True)
SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True, read_only = True)
SettingDefinition.addSupportedProperty("limit_to_extruder", DefinitionPropertyType.Function, default = "-1")
SettingDefinition.addSupportedProperty("resolve", DefinitionPropertyType.Function, default = None)
SettingDefinition.addSettingType("extruder", None, str, Validator)

definition = DefinitionContainer(os.path.basename(file_path))
with open(file_path, encoding = "utf-8") as f:
    definition.deserialize(f.read())

query = json.loads(sys.argv[2])

results = definition.findDefinitions(**query)
Example #28
0
    def __init__(self):
        Resources.addSearchPath(
            os.path.join(QtApplication.getInstallPrefix(), "share", "cura",
                         "resources"))
        if not hasattr(sys, "frozen"):
            Resources.addSearchPath(
                os.path.join(os.path.abspath(os.path.dirname(__file__)), "..",
                             "resources"))

        self._open_file_queue = []  # Files to open when plug-ins are loaded.

        # Need to do this before ContainerRegistry tries to load the machines
        SettingDefinition.addSupportedProperty("settable_per_mesh",
                                               DefinitionPropertyType.Any,
                                               default=True,
                                               read_only=True)
        SettingDefinition.addSupportedProperty("settable_per_extruder",
                                               DefinitionPropertyType.Any,
                                               default=True,
                                               read_only=True)
        # this setting can be changed for each group in one-at-a-time mode
        SettingDefinition.addSupportedProperty("settable_per_meshgroup",
                                               DefinitionPropertyType.Any,
                                               default=True,
                                               read_only=True)
        SettingDefinition.addSupportedProperty("settable_globally",
                                               DefinitionPropertyType.Any,
                                               default=True,
                                               read_only=True)

        # From which stack the setting would inherit if not defined per object (handled in the engine)
        # AND for settings which are not settable_per_mesh:
        # which extruder is the only extruder this setting is obtained from
        SettingDefinition.addSupportedProperty("limit_to_extruder",
                                               DefinitionPropertyType.Function,
                                               default="-1")

        # For settings which are not settable_per_mesh and not settable_per_extruder:
        # A function which determines the glabel/meshgroup value by looking at the values of the setting in all (used) extruders
        SettingDefinition.addSupportedProperty("resolve",
                                               DefinitionPropertyType.Function,
                                               default=None)

        SettingDefinition.addSettingType("extruder", None, str, Validator)

        SettingFunction.registerOperator(
            "extruderValues", cura.Settings.ExtruderManager.getExtruderValues)
        SettingFunction.registerOperator(
            "extruderValue", cura.Settings.ExtruderManager.getExtruderValue)
        SettingFunction.registerOperator(
            "resolveOrValue", cura.Settings.ExtruderManager.getResolveOrValue)

        ## Add the 4 types of profiles to storage.
        Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer,
                                 "quality")
        Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer,
                                 "variants")
        Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer,
                                 "materials")
        Resources.addStorageType(self.ResourceTypes.UserInstanceContainer,
                                 "user")
        Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders")
        Resources.addStorageType(self.ResourceTypes.MachineStack,
                                 "machine_instances")

        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.QualityInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.VariantInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.MaterialInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.UserInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.ExtruderStack)
        ContainerRegistry.getInstance().addResourceType(
            self.ResourceTypes.MachineStack)

        ##  Initialise the version upgrade manager with Cura's storage paths.
        import UM.VersionUpgradeManager  #Needs to be here to prevent circular dependencies.
        UM.VersionUpgradeManager.VersionUpgradeManager.getInstance(
        ).setCurrentVersions({
            ("quality", UM.Settings.InstanceContainer.Version):
            (self.ResourceTypes.QualityInstanceContainer,
             "application/x-uranium-instancecontainer"),
            ("machine_stack", UM.Settings.ContainerStack.Version):
            (self.ResourceTypes.MachineStack,
             "application/x-uranium-containerstack"),
            ("preferences", UM.Preferences.Version):
            (Resources.Preferences, "application/x-uranium-preferences"),
            ("user", UM.Settings.InstanceContainer.Version):
            (self.ResourceTypes.UserInstanceContainer,
             "application/x-uranium-instancecontainer")
        })

        self._machine_action_manager = MachineActionManager.MachineActionManager(
        )
        self._machine_manager = None  # This is initialized on demand.
        self._setting_inheritance_manager = None

        self._additional_components = {
        }  # Components to add to certain areas in the interface

        super().__init__(name="cura",
                         version=CuraVersion,
                         buildtype=CuraBuildType)

        self.setWindowIcon(
            QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))

        self.setRequiredPlugins([
            "CuraEngineBackend", "MeshView", "LayerView", "STLReader",
            "SelectionTool", "CameraTool", "GCodeWriter",
            "LocalFileOutputDevice"
        ])
        self._physics = None
        self._volume = None
        self._output_devices = {}
        self._print_information = None
        self._previous_active_tool = None
        self._platform_activity = False
        self._scene_bounding_box = AxisAlignedBox.Null

        self._job_name = None
        self._center_after_select = False
        self._camera_animation = None
        self._cura_actions = None
        self._started = False

        self._message_box_callback = None
        self._message_box_callback_arguments = []

        self._i18n_catalog = i18nCatalog("cura")

        self.getController().getScene().sceneChanged.connect(
            self.updatePlatformActivity)
        self.getController().toolOperationStopped.connect(
            self._onToolOperationStopped)

        Resources.addType(self.ResourceTypes.QmlFiles, "qml")
        Resources.addType(self.ResourceTypes.Firmware, "firmware")

        self.showSplashMessage(
            self._i18n_catalog.i18nc("@info:progress", "Loading machines..."))

        # Add empty variant, material and quality containers.
        # Since they are empty, they should never be serialized and instead just programmatically created.
        # We need them to simplify the switching between materials.
        empty_container = ContainerRegistry.getInstance(
        ).getEmptyInstanceContainer()
        empty_variant_container = copy.deepcopy(empty_container)
        empty_variant_container._id = "empty_variant"
        empty_variant_container.addMetaDataEntry("type", "variant")
        ContainerRegistry.getInstance().addContainer(empty_variant_container)
        empty_material_container = copy.deepcopy(empty_container)
        empty_material_container._id = "empty_material"
        empty_material_container.addMetaDataEntry("type", "material")
        ContainerRegistry.getInstance().addContainer(empty_material_container)
        empty_quality_container = copy.deepcopy(empty_container)
        empty_quality_container._id = "empty_quality"
        empty_quality_container.setName("Not supported")
        empty_quality_container.addMetaDataEntry("quality_type", "normal")
        empty_quality_container.addMetaDataEntry("type", "quality")
        ContainerRegistry.getInstance().addContainer(empty_quality_container)
        empty_quality_changes_container = copy.deepcopy(empty_container)
        empty_quality_changes_container._id = "empty_quality_changes"
        empty_quality_changes_container.addMetaDataEntry(
            "type", "quality_changes")
        ContainerRegistry.getInstance().addContainer(
            empty_quality_changes_container)

        # Set the filename to create if cura is writing in the config dir.
        self._config_lock_filename = os.path.join(
            Resources.getConfigStoragePath(), CONFIG_LOCK_FILENAME)
        self.waitConfigLockFile()
        ContainerRegistry.getInstance().load()

        Preferences.getInstance().addPreference("cura/active_mode", "simple")
        Preferences.getInstance().addPreference("cura/recent_files", "")
        Preferences.getInstance().addPreference("cura/categories_expanded", "")
        Preferences.getInstance().addPreference("cura/jobname_prefix", True)
        Preferences.getInstance().addPreference("view/center_on_select", True)
        Preferences.getInstance().addPreference("mesh/scale_to_fit", True)
        Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True)

        for key in [
                "dialog_load_path",  # dialog_save_path is in LocalFileOutputDevicePlugin
                "dialog_profile_path",
                "dialog_material_path"
        ]:

            Preferences.getInstance().addPreference("local_file/%s" % key,
                                                    os.path.expanduser("~/"))

        Preferences.getInstance().setDefault("local_file/last_used_type",
                                             "text/x-gcode")

        Preferences.getInstance().setDefault(
            "general/visible_settings", """
            machine_settings
            resolution
                layer_height
            shell
                wall_thickness
                top_bottom_thickness
            infill
                infill_sparse_density
            material
                material_print_temperature
                material_bed_temperature
                material_diameter
                material_flow
                retraction_enable
            speed
                speed_print
                speed_travel
                acceleration_print
                acceleration_travel
                jerk_print
                jerk_travel
            travel
            cooling
                cool_fan_enabled
            support
                support_enable
                support_extruder_nr
                support_type
                support_interface_density
            platform_adhesion
                adhesion_type
                adhesion_extruder_nr
                brim_width
                raft_airgap
                layer_0_z_overlap
                raft_surface_layers
            dual
                prime_tower_enable
                prime_tower_size
                prime_tower_position_x
                prime_tower_position_y
            meshfix
            blackmagic
                print_sequence
                infill_mesh
            experimental
        """.replace("\n", ";").replace(" ", ""))

        JobQueue.getInstance().jobFinished.connect(self._onJobFinished)

        self.applicationShuttingDown.connect(self.saveSettings)
        self.engineCreatedSignal.connect(self._onEngineCreated)
        self._recent_files = []
        files = Preferences.getInstance().getValue("cura/recent_files").split(
            ";")
        for f in files:
            if not os.path.isfile(f):
                continue

            self._recent_files.append(QUrl.fromLocalFile(f))
    def _onContainerLoadComplete(self, container_id: str) -> None:
        if not ContainerRegistry.getInstance().isLoaded(container_id):
            # skip containers that could not be loaded, or subsequent findContainers() will cause an infinite loop
            return

        try:
            container = ContainerRegistry.getInstance().findContainers(
                id=container_id)[0]
        except IndexError:
            # the container no longer exists
            return

        if not isinstance(container, DefinitionContainer):
            # skip containers that are not definitions
            return
        if container.getMetaDataEntry("type") == "extruder":
            # skip extruder definitions
            return

        try:
            category = container.findDefinitions(key="blackmagic")[0]
        except IndexError:
            Logger.log(
                "e",
                "Could not find parent category setting to add settings to")
            return

        for setting_key in self._settings_dict.keys():
            setting_definition = SettingDefinition(setting_key, container,
                                                   category,
                                                   self._i18n_catalog)
            setting_definition.deserialize(self._settings_dict[setting_key])

            # add the setting to the already existing blackmagic settingdefinition
            # private member access is naughty, but the alternative is to serialise, nix and deserialise the whole thing,
            # which breaks stuff
            category._children.append(setting_definition)
            container._definition_cache[setting_key] = setting_definition

            self._expanded_categories = self._application.expandedCategories.copy(
            )
            self._updateAddedChildren(container, setting_definition)
            self._application.setExpandedCategories(self._expanded_categories)
            self._expanded_categories.clear()
            container._updateRelations(setting_definition)

        preferences = self._application.getPreferences()
        if not preferences.getValue("arcwelderplugin/settings_made_visible"):
            setting_keys = self._getAllSettingKeys(self._settings_dict)

            visible_settings = preferences.getValue("general/visible_settings")
            visible_settings_changed = False
            for key in setting_keys:
                if key not in visible_settings:
                    visible_settings += ";%s" % key
                    visible_settings_changed = True

            if visible_settings_changed:
                preferences.setValue("general/visible_settings",
                                     visible_settings)

            preferences.setValue("arcwelderplugin/settings_made_visible", True)
        html += formatKeyValueTableRow("read only",
                                       safeCall(def_container.isReadOnly),
                                       extra_class="metadata")
        html += formatKeyValueTableRow("path",
                                       safeCall(def_container.getPath),
                                       extra_class="metadata")
        html += formatKeyValueTableRow("metadata",
                                       safeCall(def_container.getMetaData),
                                       extra_class="metadata")
    except:
        pass

    return html


setting_prop_names = SettingDefinition.getPropertyNames()


def formatSettingValue(container, key, properties=None):
    if properties is None:
        properties = setting_prop_names

    value = "<ul class=\"property_list\">\n"
    comma = ""
    properties.sort()
    for prop_name in properties:
        prop_value = container.getProperty(key, prop_name)
        if prop_value is not None:
            value += "  <li>\n"
            value += "    <span class='prop_name'>" + encode(
                prop_name) + ":</span> " + encode(repr(prop_value))
Example #31
0
    def __init__(self):
        Resources.addSearchPath(os.path.join(QtApplication.getInstallPrefix(), "share", "cura", "resources"))
        if not hasattr(sys, "frozen"):
            Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources"))

        self._open_file_queue = []  # Files to open when plug-ins are loaded.

        # Need to do this before ContainerRegistry tries to load the machines
        SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False)
        SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator)

        super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType)

        self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))

        self.setRequiredPlugins([
            "CuraEngineBackend",
            "MeshView",
            "LayerView",
            "STLReader",
            "SelectionTool",
            "CameraTool",
            "GCodeWriter",
            "LocalFileOutputDevice"
        ])
        self._physics = None
        self._volume = None
        self._platform = None
        self._output_devices = {}
        self._print_information = None
        self._i18n_catalog = None
        self._previous_active_tool = None
        self._platform_activity = False
        self._scene_bounding_box = AxisAlignedBox()
        self._job_name = None
        self._center_after_select = False
        self._camera_animation = None
        self._cura_actions = None
        self._started = False

        self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity)
        self.getController().toolOperationStopped.connect(self._onToolOperationStopped)

        Resources.addType(self.ResourceTypes.QmlFiles, "qml")
        Resources.addType(self.ResourceTypes.Firmware, "firmware")

        ## Add the 4 types of profiles to storage.
        Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality")
        Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants")
        Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials")
        Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user")
        Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders")
        Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances")

        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.ExtruderStack)
        ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack)

        # Add empty variant, material and quality containers.
        # Since they are empty, they should never be serialized and instead just programmatically created.
        # We need them to simplify the switching between materials.
        empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
        empty_variant_container = copy.deepcopy(empty_container)
        empty_variant_container._id = "empty_variant"
        empty_variant_container.addMetaDataEntry("type", "variant")
        ContainerRegistry.getInstance().addContainer(empty_variant_container)
        empty_material_container = copy.deepcopy(empty_container)
        empty_material_container._id = "empty_material"
        empty_material_container.addMetaDataEntry("type", "material")
        ContainerRegistry.getInstance().addContainer(empty_material_container)
        empty_quality_container = copy.deepcopy(empty_container)
        empty_quality_container._id = "empty_quality"
        empty_quality_container.addMetaDataEntry("type", "quality")
        ContainerRegistry.getInstance().addContainer(empty_quality_container)

        ContainerRegistry.getInstance().load()

        Preferences.getInstance().addPreference("cura/active_mode", "simple")
        Preferences.getInstance().addPreference("cura/recent_files", "")
        Preferences.getInstance().addPreference("cura/categories_expanded", "")
        Preferences.getInstance().addPreference("cura/jobname_prefix", True)
        Preferences.getInstance().addPreference("view/center_on_select", True)
        Preferences.getInstance().addPreference("mesh/scale_to_fit", True)
        Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True)
        Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode")

        Preferences.getInstance().setDefault("general/visible_settings", """
            machine_settings
                resolution
                layer_height
            shell
                wall_thickness
                top_bottom_thickness
            infill
                infill_sparse_density
            material
                material_print_temperature
                material_bed_temperature
                material_diameter
                material_flow
                retraction_enable
            speed
                speed_print
                speed_travel
            travel
            cooling
                cool_fan_enabled
            support
                support_enable
                support_type
                support_roof_density
            platform_adhesion
                adhesion_type
                brim_width
                raft_airgap
                layer_0_z_overlap
                raft_surface_layers
            meshfix
            blackmagic
                print_sequence
                dual
            experimental
        """.replace("\n", ";").replace(" ", ""))

        JobQueue.getInstance().jobFinished.connect(self._onJobFinished)

        self.applicationShuttingDown.connect(self.saveSettings)

        self._recent_files = []
        files = Preferences.getInstance().getValue("cura/recent_files").split(";")
        for f in files:
            if not os.path.isfile(f):
                continue

            self._recent_files.append(QUrl.fromLocalFile(f))