def test_getUsedSettings(data):
    function = SettingFunction(data["code"])
    answer = function.getUsedSettingKeys()
    assert len(answer) == len(data["variables"])
    for variable in data[
            "variables"]:  # Check for set equality regardless of the order.
        assert variable in answer
def test_eq():
    setting_function = SettingFunction("3 * 3")
    assert not (setting_function == "some string"
                )  # Equality against something of a different type.
    assert setting_function != "some string"
    assert setting_function == setting_function  # Equality against itself.
    assert not (setting_function != setting_function)

    duplicate = SettingFunction(
        "3 * 3")  # Different instance with the same code. Should be equal!
    assert setting_function == duplicate
    assert not (setting_function != duplicate)

    same_answer = SettingFunction(
        "9")  # Different code but the result is the same. Should NOT be equal!
    assert not (setting_function == same_answer)
    assert setting_function != same_answer
    def _modifyInfillAnglesInSettingDict(self, settings):
        for key, value in settings.items():
            if key == "infill_angles":
                if type(value) is str:
                    value = SettingFunction(value)(self._propertyHandler)
                if len(value) == 0:
                    settings[key] = [self.INFILL_DIRECTION]
                else:
                    settings[key] = [value[0]]

        return settings
示例#4
0
def test_getUsedSettings(data):
    function = SettingFunction(data["code"])
    answer = function.getUsedSettingKeys()
    assert len(answer) == len(data["variables"])
    for variable in data["variables"]: # Check for set equality regardless of the order.
        assert variable in answer
示例#5
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 setting_function_bad(request):
    return SettingFunction(request.param)
def test_str():
    # Due to the simplicity of the function, it's not really necessary to make a full-blown parametrised test for this. Just two simple tests:
    function = SettingFunction("3.14156")  # Simple test case.
    assert str(function) == "=3.14156"
    function = SettingFunction("")  # Also the edge case.
    assert str(function) == "="
def test_call(data):
    value_provider = MockValueProvider()
    function = SettingFunction(data["code"])
    assert function(value_provider) == data["result"]
示例#9
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))
        "label": "Test",
        "default_value": 1,
        "description": "Test Setting",
        "type": "int",
        "unit": "mm"
    }, {
        "unit": "mm"
    }),
    ({
        "label": "Test",
        "default_value": 1,
        "description": "Test Setting",
        "type": "int",
        "value": "10"
    }, {
        "value": SettingFunction("10")
    }),
]


@pytest.mark.parametrize("data,expected", test_basic_properties_data)
def test_basic_properties(data, expected):
    definition = UM.Settings.SettingDefinition.SettingDefinition("test", None)

    definition.deserialize(data)

    for key, value in expected.items():
        assert getattr(definition, key) == value


def test_missing_properties():
示例#11
0
from unittest.mock import patch, MagicMock

import pytest

from UM.Settings.SettingFunction import SettingFunction
from UM.Settings.SettingInstance import InstanceState
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager

setting_function = SettingFunction("")
setting_function.getUsedSettingKeys = MagicMock(return_value=["omg", "zomg"])

setting_property_dict = {
    "setting_1": {},
    "setting_2": {
        "state": InstanceState.User,
        "enabled": False
    },
    "setting_3": {
        "state": InstanceState.User,
        "enabled": True
    },
    "setting_4": {
        "state": InstanceState.User,
        "enabled": True,
        "value": 12
    },
    "setting_5": {
        "state": InstanceState.User,
        "enabled": True,
        "value": setting_function
    }
from unittest.mock import patch, MagicMock

import pytest

from UM.Settings.SettingFunction import SettingFunction
from UM.Settings.SettingInstance import InstanceState
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager

setting_function = SettingFunction("")
setting_function.getUsedSettingKeys = MagicMock(return_value = ["omg", "zomg"])

setting_property_dict = {"setting_1": {},
                         "setting_2": {"state": InstanceState.User, "enabled": False},
                         "setting_3": {"state": InstanceState.User, "enabled": True},
                         "setting_4": {"state": InstanceState.User, "enabled": True, "value": 12},
                         "setting_5": {"state": InstanceState.User, "enabled": True, "value": setting_function}}


def getPropertySideEffect(*args, **kwargs):
    properties = setting_property_dict.get(args[0])
    if properties:
        return properties.get(args[1])


@pytest.fixture
def setting_inheritance_manager():
    with patch("UM.Application.Application.getInstance"):
        with patch("cura.Settings.ExtruderManager.ExtruderManager.getInstance"):
            return SettingInheritanceManager()

@pytest.fixture
    def checkJob(self, machine_name="printer", show_extruder_warnings=False) -> Tuple[pywim.smartslice.job.Job, Dict[str, str]]:

        if len(getPrintableNodes()) == 0:
            return None, {}

        # Create a new instance of errors. We will use this to replace the old errors and
        # emit a signal to replace them
        errors = []

        if len(getPrintableNodes()) != 1:
            errors.append(pywim.smartslice.val.InvalidSetup(
                "Invalid number of printable models on the build tray",
                "Only 1 printable model is currently supported"
            ))

        # We build a new job from scratch evertime - it's easier than trying to manage a whole bunch of changes
        job = pywim.smartslice.job.Job()

        # Extruder Manager
        extruderManager = Application.getInstance().getExtruderManager()
        emActive = extruderManager._active_extruder_index

        # Normal mesh
        normal_mesh = getPrintableNodes()[0]

        # Get all nodes to cycle through
        nodes = [normal_mesh] + getModifierMeshes()

        # Cycle through all of the meshes and check extruder
        for node in nodes:
            active_extruder = getNodeActiveExtruder(node)

            # Build the data for Smart Slice error checking
            mesh = pywim.chop.mesh.Mesh(node.getName())
            mesh.print_config.auxiliary = self._getAuxDict(node.callDecoration("getStack"))
            job.chop.meshes.add(mesh)

            # Check the active extruder
            any_individual_extruder = all(map(lambda k : (int(active_extruder.getProperty(k, "value")) <= 0), ExtruderProperty.EXTRUDER_KEYS))
            if not ( int(active_extruder.getMetaDataEntry("position")) == 0 and int(emActive) == 0 and any_individual_extruder ):
                errors.append(pywim.smartslice.val.InvalidSetup(
                    "Invalid extruder selected for <i>{}</i>".format(node.getName()),
                    "Change active extruder to Extruder 1"
                ))
                show_extruder_warnings = False # Turn the warnings off - we aren't on the right extruder

        # Check the material
        machine_extruder = getNodeActiveExtruder(normal_mesh)
        guid = machine_extruder.material.getMetaData().get("GUID", "")
        material, tested = self.getMaterial(guid)

        if not material:
            errors.append(pywim.smartslice.val.InvalidSetup(
                "Material <i>{}</i> is not currently supported for Smart Slice".format(machine_extruder.material.name),
                "Please select a supported material."
            ))
        else:
            if not tested and show_extruder_warnings:
                self._material_warning.setText(i18n_catalog.i18nc(
                    "@info:status", "Material <b>{}</b> has not been tested for Smart Slice. A generic equivalent will be used.".format(machine_extruder.material.name)
                ))
                self._material_warning.show()

                self.materialWarning.emit(guid)
            elif tested:
                self._material_warning.hide()

            job.bulk.add(
                pywim.fea.model.Material.from_dict(material)
            )

        # Use Cases
        smart_sliceScene_node = findChildSceneNode(getPrintableNodes()[0], Root)
        if smart_sliceScene_node:
            job.chop.steps = smart_sliceScene_node.createSteps()

        # Requirements
        req_tool = SmartSliceRequirements.getInstance()
        job.optimization.min_safety_factor = req_tool.targetSafetyFactor
        job.optimization.max_displacement = req_tool.maxDisplacement

        # Global print config -- assuming only 1 extruder is active for ALL meshes right now
        print_config = pywim.am.Config()
        print_config.layer_height = self._propertyHandler.getGlobalProperty("layer_height")
        print_config.layer_width = self._propertyHandler.getExtruderProperty("line_width")
        print_config.walls = self._propertyHandler.getExtruderProperty("wall_line_count")
        print_config.bottom_layers = self._propertyHandler.getExtruderProperty("top_layers")
        print_config.top_layers = self._propertyHandler.getExtruderProperty("bottom_layers")

        # > https://github.com/Ultimaker/CuraEngine/blob/master/src/FffGcodeWriter.cpp#L402
        skin_angles = self._propertyHandler.getExtruderProperty("skin_angles")
        if type(skin_angles) is str:
            skin_angles = SettingFunction(skin_angles)(self._propertyHandler)
        if len(skin_angles) > 0:
            print_config.skin_orientations.extend(tuple(skin_angles))
        else:
            print_config.skin_orientations.extend((45, 135))

        infill_pattern = self._propertyHandler.getExtruderProperty("infill_pattern")
        print_config.infill.density = self._propertyHandler.getExtruderProperty("infill_sparse_density")
        if infill_pattern in self.INFILL_CURA_SMARTSLICE.keys():
            print_config.infill.pattern = self.INFILL_CURA_SMARTSLICE[infill_pattern]
        else:
            print_config.infill.pattern = infill_pattern # The job validation will handle the error

        # > https://github.com/Ultimaker/CuraEngine/blob/master/src/FffGcodeWriter.cpp#L366
        infill_angles = self._propertyHandler.getExtruderProperty("infill_angles")
        if type(infill_angles) is str:
            infill_angles = SettingFunction(infill_angles)(self._propertyHandler)
        if len(infill_angles) == 0:
            print_config.infill.orientation = self.INFILL_DIRECTION
        else:
            if len(infill_angles) > 1:
                Logger.log("w", "More than one infill angle is set! Only the first will be taken!")
                Logger.log("d", "Ignoring the angles: {}".format(infill_angles[1:]))
            print_config.infill.orientation = infill_angles[0]

        print_config.auxiliary = self._getAuxDict(
            Application.getInstance().getGlobalContainerStack()
        )

        # Extruder config
        extruders = ()
        machine_extruder = getNodeActiveExtruder(normal_mesh)
        for extruder_stack in [machine_extruder]:
            extruder = pywim.chop.machine.Extruder(diameter=extruder_stack.getProperty("machine_nozzle_size", "value"))
            extruder.print_config.auxiliary = self._getAuxDict(extruder_stack)
            extruders += (extruder,)

        printer = pywim.chop.machine.Printer(name=machine_name, extruders=extruders)
        job.chop.slicer = pywim.chop.slicer.CuraEngine(config=print_config, printer=printer)

        # Check the job and add the errors
        errors = errors + job.validate()

        error_dict = {}
        for err in errors:
            error_dict[err.error()] = err.resolution()

        return job, error_dict
示例#14
0
                                       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)

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

cr = cura.Settings.CuraContainerRegistry.getInstance()
cr.setApplication(dummyApp)

cr.addResourceType(dummyApp.ResourceTypes.QualityInstanceContainer)
cr.addResourceType(dummyApp.ResourceTypes.VariantInstanceContainer)
cr.addResourceType(dummyApp.ResourceTypes.MaterialInstanceContainer)
cr.addResourceType(dummyApp.ResourceTypes.UserInstanceContainer)
cr.addResourceType(dummyApp.ResourceTypes.ExtruderStack)
cr.addResourceType(dummyApp.ResourceTypes.MachineStack)