def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if not global_container_stack:
            return []

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)

        # Get the  list of extruders and place the selected extruder at the front of the list.
        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = extruder_manager.getActiveExtruderStacks()
        if active_extruder in extruder_stacks:
            extruder_stacks.remove(active_extruder)
            extruder_stacks = [active_extruder] + extruder_stacks

        # Fetch the list of useable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        quality_list =  QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                                                                  extruder_stacks)

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
        filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set]

        return quality_list + filtered_quality_changes
    def removeQualityChanges(self, quality_name):
        Logger.log("d", "Attempting to remove the quality change containers with name %s", quality_name)
        containers_found = False

        if not quality_name:
            return containers_found  # Without a name we will never find a container to remove.

        # If the container that is being removed is the currently active quality, set another quality as the active quality
        activate_quality = quality_name == self._machine_manager.activeQualityName
        activate_quality_type = None

        global_stack = Application.getInstance().getGlobalContainerStack()
        if not global_stack or not quality_name:
            return ""
        machine_definition = QualityManager.getInstance().getParentMachineDefinition(global_stack.getBottom())

        for container in QualityManager.getInstance().findQualityChangesByName(quality_name, machine_definition):
            containers_found = True
            if activate_quality and not activate_quality_type:
                activate_quality_type = container.getMetaDataEntry("quality")
            self._container_registry.removeContainer(container.getId())

        if not containers_found:
            Logger.log("d", "Unable to remove quality containers, as we did not find any by the name of %s", quality_name)

        elif activate_quality:
            definition_id = "fdmprinter" if not self._machine_manager.filterQualityByMachine else self._machine_manager.activeDefinitionId
            containers = self._container_registry.findInstanceContainers(type = "quality", definition = definition_id, quality_type = activate_quality_type)
            if containers:
                self._machine_manager.setActiveQuality(containers[0].getId())
                self._machine_manager.activeQualityChanged.emit()

        return containers_found
Beispiel #3
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if global_container_stack is None:
            return {}, {}
        global_stack_definition = global_container_stack.definition

        # Get the list of extruders and place the selected extruder at the front of the list.
        extruder_stacks = self._getOrderedExtruderStacksList()
        materials = [extruder.material for extruder in extruder_stacks]

        # Fetch the list of usable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        result = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)

        # The usable quality types are set
        quality_type_set = set([x.getMetaDataEntry("quality_type") for x in result])

        # Fetch all qualities available for this machine and the materials selected in extruders
        all_qualities = QualityManager.getInstance().findAllQualitiesForMachineAndMaterials(global_stack_definition, materials)

        # If in the all qualities there is some of them that are not available due to incompatibility with materials
        # we also add it so that they will appear in the slide quality bar. However in recomputeItems will be marked as
        # not available so they will be shown in gray
        for quality in all_qualities:
            if quality.getMetaDataEntry("quality_type") not in quality_type_set:
                result.append(quality)

        # if still profiles are found, add a single empty_quality ("Not supported") instance to the drop down list
        if len(result) == 0:
            # If not qualities are found we dynamically create a not supported container for this machine + material combination
            not_supported_container = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0]
            result.append(not_supported_container)

        return {item.getId():item for item in result}, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet.
Beispiel #4
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if not global_container_stack:
            return []

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(
            global_container_stack.getBottom())
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(
            machine_definition)

        # Fetch the list of qualities
        quality_list = QualityManager.getInstance(
        ).findAllUsableQualitiesForMachineAndExtruders(
            global_container_stack,
            ExtruderManager.getInstance().getActiveExtruderStacks())

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set(
            [x.getMetaDataEntry("quality_type") for x in quality_list])
        filtered_quality_changes = [
            qc for qc in quality_changes_list
            if qc.getMetaDataEntry("quality_type") in quality_type_set
        ]

        return filtered_quality_changes
Beispiel #5
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if global_container_stack is None:
            return {}, {}
        global_stack_definition = global_container_stack.definition

        # Get the list of extruders and place the selected extruder at the front of the list.
        extruder_stacks = self._getOrderedExtruderStacksList()
        materials = [extruder.material for extruder in extruder_stacks]

        # Fetch the list of usable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        result = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)

        # The usable quality types are set
        quality_type_set = set([x.getMetaDataEntry("quality_type") for x in result])

        # Fetch all qualities available for this machine and the materials selected in extruders
        all_qualities = QualityManager.getInstance().findAllQualitiesForMachineAndMaterials(global_stack_definition, materials)

        # If in the all qualities there is some of them that are not available due to incompatibility with materials
        # we also add it so that they will appear in the slide quality bar. However in recomputeItems will be marked as
        # not available so they will be shown in gray
        for quality in all_qualities:
            if quality.getMetaDataEntry("quality_type") not in quality_type_set:
                result.append(quality)

        if len(result) > 1 and self._empty_quality in result:
            result.remove(self._empty_quality)

        return {item.getId(): item for item in result}, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet.
Beispiel #6
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if global_container_stack is None:
            return []
        global_stack_definition = global_container_stack.getBottom()

        # Get the list of extruders and place the selected extruder at the front of the list.
        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = extruder_manager.getActiveExtruderStacks()
        if active_extruder in extruder_stacks:
            extruder_stacks.remove(active_extruder)
            extruder_stacks = [active_extruder] + extruder_stacks

        if ExtruderManager.getInstance().getActiveExtruderStacks():
            # Multi-extruder machine detected.
            materials = [extruder.material for extruder in extruder_stacks]
        else:
            # Machine with one extruder.
            materials = [global_container_stack.material]

        # Fetch the list of usable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        result = QualityManager.getInstance(
        ).findAllQualitiesForMachineAndMaterials(global_stack_definition,
                                                 materials)

        for quality in QualityManager.getInstance(
        ).findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                       extruder_stacks):
            if quality not in result:
                result.append(quality)
        return result
Beispiel #7
0
    def removeQualityChanges(self, quality_name):
        Logger.log("d", "Attempting to remove the quality change containers with name %s", quality_name)
        containers_found = False

        if not quality_name:
            return containers_found  # Without a name we will never find a container to remove.

        # If the container that is being removed is the currently active quality, set another quality as the active quality
        activate_quality = quality_name == self._machine_manager.activeQualityName
        activate_quality_type = None

        global_stack = Application.getInstance().getGlobalContainerStack()
        if not global_stack or not quality_name:
            return ""
        machine_definition = QualityManager.getInstance().getParentMachineDefinition(global_stack.getBottom())

        for container in QualityManager.getInstance().findQualityChangesByName(quality_name, machine_definition):
            containers_found = True
            if activate_quality and not activate_quality_type:
                activate_quality_type = container.getMetaDataEntry("quality")
            self._container_registry.removeContainer(container.getId())

        if not containers_found:
            Logger.log("d", "Unable to remove quality containers, as we did not find any by the name of %s", quality_name)

        elif activate_quality:
            definition_id = "fdmprinter" if not self._machine_manager.filterQualityByMachine else self._machine_manager.activeDefinitionId
            containers = self._container_registry.findInstanceContainers(type = "quality", definition = definition_id, quality_type = activate_quality_type)
            if containers:
                self._machine_manager.setActiveQuality(containers[0].getId())
                self._machine_manager.activeQualityChanged.emit()

        return containers_found
Beispiel #8
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if global_container_stack is None:
            return []
        global_stack_definition = global_container_stack.getBottom()

        # Get the list of extruders and place the selected extruder at the front of the list.
        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = extruder_manager.getActiveExtruderStacks()
        materials = [global_container_stack.material]

        if active_extruder in extruder_stacks:
            extruder_stacks.remove(active_extruder)
            extruder_stacks = [active_extruder] + extruder_stacks
            materials = [extruder.material for extruder in extruder_stacks]

        # Fetch the list of usable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        result = QualityManager.getInstance(
        ).findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                       extruder_stacks)

        # The usable quality types are set
        quality_type_set = set(
            [x.getMetaDataEntry("quality_type") for x in result])

        # Fetch all qualities available for this machine and the materials selected in extruders
        all_qualities = QualityManager.getInstance(
        ).findAllQualitiesForMachineAndMaterials(global_stack_definition,
                                                 materials)

        # If in the all qualities there is some of them that are not available due to incompatibility with materials
        # we also add it so that they will appear in the slide quality bar. However in recomputeItems will be marked as
        # not available so they will be shown in gray
        for quality in all_qualities:
            if quality.getMetaDataEntry(
                    "quality_type") not in quality_type_set:
                result.append(quality)

        # if still profiles are found, add a single empty_quality ("Not supported") instance to the drop down list
        if len(result) == 0:
            # If not qualities are found we dynamically create a not supported container for this machine + material combination
            not_supported_container = ContainerRegistry.getInstance(
            ).findContainers(id="empty_quality")[0]
            result.append(not_supported_container)

        return result
Beispiel #9
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if not global_container_stack:
            return []

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(
            global_container_stack.definition)
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(
            machine_definition)

        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = self._getOrderedExtruderStacksList()

        # Fetch the list of usable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(
            global_container_stack, extruder_stacks)

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set(
            [x.getMetaDataEntry("quality_type") for x in quality_list])
        filtered_quality_changes = [
            qc for qc in quality_changes_list
            if qc.getMetaDataEntry("quality_type") in quality_type_set
            and qc.getMetaDataEntry("extruder") is not None and (
                qc.getMetaDataEntry("extruder") == active_extruder.definition.
                getMetaDataEntry("quality_definition") or qc.getMetaDataEntry(
                    "extruder") == active_extruder.definition.getId())
        ]

        return quality_list + filtered_quality_changes
Beispiel #10
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if not global_container_stack:
            return {}, {}

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)

        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = self._getOrderedExtruderStacksList()

        # Fetch the list of usable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
        # Also show custom profiles based on "Not Supported" quality profile
        quality_type_set.add(self._empty_quality.getMetaDataEntry("quality_type"))
        filtered_quality_changes = {qc.getId(): qc for qc in quality_changes_list if
                                    qc.getMetaDataEntry("quality_type") in quality_type_set and
                                    qc.getMetaDataEntry("extruder") is not None and
                                    (qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
                                     qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())}

        result = filtered_quality_changes
        for q in quality_list:
            if q.getId() != "empty_quality":
                result[q.getId()] = q
        return result, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet.
Beispiel #11
0
    def _createQualityChanges(self, quality_container, new_name,
                              machine_definition, extruder_id):
        base_id = machine_definition.getId(
        ) if extruder_id is None else extruder_id

        # Create a new quality_changes container for the quality.
        quality_changes = UM.Settings.InstanceContainer(
            self._createUniqueId(base_id, new_name))
        quality_changes.setName(new_name)
        quality_changes.addMetaDataEntry("type", "quality_changes")
        quality_changes.addMetaDataEntry(
            "quality_type", quality_container.getMetaDataEntry("quality_type"))

        # If we are creating a container for an extruder, ensure we add that to the container
        if extruder_id is not None:
            quality_changes.addMetaDataEntry("extruder", extruder_id)

        # If the machine specifies qualities should be filtered, ensure we match the current criteria.
        if not machine_definition.getMetaDataEntry("has_machine_quality"):
            quality_changes.setDefinition(
                self._container_registry.findContainers(id="fdmprinter")[0])
        else:
            quality_changes.setDefinition(
                QualityManager.getInstance().getParentMachineDefinition(
                    machine_definition))
        return quality_changes
Beispiel #12
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if not global_container_stack:
            return {}, {}

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)

        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = self._getOrderedExtruderStacksList()

        # Fetch the list of usable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])

        filtered_quality_changes = {qc.getId():qc for qc in quality_changes_list if
                                    qc.getMetaDataEntry("quality_type") in quality_type_set and
                                    qc.getMetaDataEntry("extruder") is not None and
                                    (qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
                                     qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())}

        return filtered_quality_changes, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet.
    def _configureProfile(self, profile: InstanceContainer, id_seed: str, new_name: str) -> Optional[str]:
        profile.setDirty(True)  # Ensure the profiles are correctly saved

        new_id = self.createUniqueName("quality_changes", "", id_seed, catalog.i18nc("@label", "Custom profile"))
        profile.setMetaDataEntry("id", new_id)
        profile.setName(new_name)

        # Set the unique Id to the profile, so it's generating a new one even if the user imports the same profile
        # It also solves an issue with importing profiles from G-Codes
        profile.setMetaDataEntry("id", new_id)

        if "type" in profile.getMetaData():
            profile.setMetaDataEntry("type", "quality_changes")
        else:
            profile.addMetaDataEntry("type", "quality_changes")

        quality_type = profile.getMetaDataEntry("quality_type")
        if not quality_type:
            return catalog.i18nc("@info:status", "Profile is missing a quality type.")

        quality_type_criteria = {"quality_type": quality_type}
        if self._machineHasOwnQualities():
            profile.setDefinition(self._activeQualityDefinition().getId())
            if self._machineHasOwnMaterials():
                active_material_id = self._activeMaterialId()
                if active_material_id and active_material_id != "empty":  # only update if there is an active material
                    profile.addMetaDataEntry("material", active_material_id)
                    quality_type_criteria["material"] = active_material_id

            quality_type_criteria["definition"] = profile.getDefinition().getId()

        else:
            profile.setDefinition("fdmprinter")
            quality_type_criteria["definition"] = "fdmprinter"

        machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
        del quality_type_criteria["definition"]

        # materials = None

        if "material" in quality_type_criteria:
            # materials = ContainerRegistry.getInstance().findInstanceContainers(id = quality_type_criteria["material"])
            del quality_type_criteria["material"]

        # Do not filter quality containers here with materials because we are trying to import a profile, so it should
        # NOT be restricted by the active materials on the current machine.
        materials = None

        # Check to make sure the imported profile actually makes sense in context of the current configuration.
        # This prevents issues where importing a "draft" profile for a machine without "draft" qualities would report as
        # successfully imported but then fail to show up.
        from cura.QualityManager import QualityManager
        qualities = QualityManager.getInstance()._getFilteredContainersForStack(machine_definition, materials, **quality_type_criteria)
        if not qualities:
            return catalog.i18nc("@info:status", "Could not find a quality type {0} for the current configuration.", quality_type)

        ContainerRegistry.getInstance().addContainer(profile)

        return None
Beispiel #14
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if not global_container_stack:
            return []

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)

        # Fetch the list of qualities
        quality_list =  QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                              ExtruderManager.getInstance().getActiveExtruderStacks())

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
        filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set]

        return filtered_quality_changes
Beispiel #15
0
    def _configureProfile(self, profile: InstanceContainer, id_seed: str, new_name: str) -> Optional[str]:
        profile.setDirty(True)  # Ensure the profiles are correctly saved

        new_id = self.createUniqueName("quality_changes", "", id_seed, catalog.i18nc("@label", "Custom profile"))
        profile._id = new_id
        profile.setName(new_name)

        if "type" in profile.getMetaData():
            profile.setMetaDataEntry("type", "quality_changes")
        else:
            profile.addMetaDataEntry("type", "quality_changes")

        quality_type = profile.getMetaDataEntry("quality_type")
        if not quality_type:
            return catalog.i18nc("@info:status", "Profile is missing a quality type.")

        quality_type_criteria = {"quality_type": quality_type}
        if self._machineHasOwnQualities():
            profile.setDefinition(self._activeQualityDefinition().getId())
            if self._machineHasOwnMaterials():
                active_material_id = self._activeMaterialId()
                if active_material_id and active_material_id != "empty":  # only update if there is an active material
                    profile.addMetaDataEntry("material", active_material_id)
                    quality_type_criteria["material"] = active_material_id

            quality_type_criteria["definition"] = profile.getDefinition().getId()

        else:
            profile.setDefinition(fdmprinter)
            quality_type_criteria["definition"] = "fdmprinter"

        machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
        del quality_type_criteria["definition"]

        # materials = None

        if "material" in quality_type_criteria:
            # materials = ContainerRegistry.getInstance().findInstanceContainers(id = quality_type_criteria["material"])
            del quality_type_criteria["material"]

        # Do not filter quality containers here with materials because we are trying to import a profile, so it should
        # NOT be restricted by the active materials on the current machine.
        materials = None

        # Check to make sure the imported profile actually makes sense in context of the current configuration.
        # This prevents issues where importing a "draft" profile for a machine without "draft" qualities would report as
        # successfully imported but then fail to show up.
        from cura.QualityManager import QualityManager
        qualities = QualityManager.getInstance()._getFilteredContainersForStack(machine_definition, materials, **quality_type_criteria)
        if not qualities:
            return catalog.i18nc("@info:status", "Could not find a quality type {0} for the current configuration.", quality_type)

        ContainerRegistry.getInstance().addContainer(profile)

        return None
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if not global_container_stack:
            return []

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(
            global_container_stack.getBottom())
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(
            machine_definition)

        # Detecting if the machine has multiple extrusion
        multiple_extrusion = global_container_stack.getProperty(
            "machine_extruder_count", "value") > 1
        # Get the  list of extruders
        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = extruder_manager.getActiveExtruderStacks()
        if multiple_extrusion:
            # Place the active extruder at the front of the list.
            extruder_stacks.remove(active_extruder)
            extruder_stacks = [active_extruder] + extruder_stacks

        # Fetch the list of useable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(
            global_container_stack, extruder_stacks)

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set(
            [x.getMetaDataEntry("quality_type") for x in quality_list])

        if multiple_extrusion:
            # If the printer has multiple extruders then quality changes related to the current extruder are kept
            filtered_quality_changes = [
                qc for qc in quality_changes_list
                if qc.getMetaDataEntry("quality_type") in quality_type_set
                and qc.getMetaDataEntry("extruder") is not None and
                qc.getMetaDataEntry("extruder") == active_extruder.definition.
                getMetaDataEntry("quality_definition") or qc.getMetaDataEntry(
                    "extruder") == active_extruder.definition.getId()
            ]
        else:
            # If not, the quality changes of the global stack are selected
            filtered_quality_changes = [
                qc for qc in quality_changes_list
                if qc.getMetaDataEntry("quality_type") in quality_type_set
                and qc.getMetaDataEntry("extruder") is None
            ]

        return quality_list + filtered_quality_changes
Beispiel #17
0
    def _duplicateQualityOrQualityChangesForMachineType(self, quality_name, base_name, machine_definition, material_instances):
        Logger.log("d", "Attempting to duplicate the quality %s", quality_name)

        if base_name is None:
            base_name = quality_name
        # Try to find a Quality with the name.
        container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances)
        if container:
            Logger.log("d", "We found a quality to duplicate.")
            return self._duplicateQualityForMachineType(container, base_name, machine_definition)
        Logger.log("d", "We found a quality_changes to duplicate.")
        # Assume it is a quality changes.
        return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition)
    def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition):
        new_change_instances = []
        for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name,
                                                              machine_definition):
            base_id = container.getMetaDataEntry("extruder")
            if not base_id:
                base_id = container.getDefinition().getId()
            new_unique_id = self._createUniqueId(base_id, base_name)
            new_container = container.duplicate(new_unique_id, base_name)
            new_change_instances.append(new_container)
            self._container_registry.addContainer(new_container)

        return new_change_instances
    def _duplicateQualityOrQualityChangesForMachineType(self, quality_name, base_name, machine_definition, material_instances):
        Logger.log("d", "Attempting to duplicate the quality %s", quality_name)

        if base_name is None:
            base_name = quality_name
        # Try to find a Quality with the name.
        container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances)
        if container:
            Logger.log("d", "We found a quality to duplicate.")
            return self._duplicateQualityForMachineType(container, base_name, machine_definition)
        Logger.log("d", "We found a quality_changes to duplicate.")
        # Assume it is a quality changes.
        return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition)
    def duplicateQualityOrQualityChanges(self, quality_name, base_name):
        global_stack = Application.getInstance().getGlobalContainerStack()
        if not global_stack or not quality_name:
            return ""
        machine_definition = global_stack.getBottom()

        active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
        material_containers = [stack.material for stack in active_stacks]

        result = self._duplicateQualityOrQualityChangesForMachineType(quality_name, base_name,
                    QualityManager.getInstance().getParentMachineDefinition(machine_definition),
                    material_containers)
        return result[0].getName() if result else ""
Beispiel #21
0
    def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition):
        new_change_instances = []
        for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name,
                                                              machine_definition):
            base_id = container.getMetaDataEntry("extruder")
            if not base_id:
                base_id = container.getDefinition().getId()
            new_unique_id = self._createUniqueId(base_id, base_name)
            new_container = container.duplicate(new_unique_id, base_name)
            new_change_instances.append(new_container)
            self._container_registry.addContainer(new_container)

        return new_change_instances
Beispiel #22
0
    def duplicateQualityOrQualityChanges(self, quality_name, base_name):
        global_stack = Application.getInstance().getGlobalContainerStack()
        if not global_stack or not quality_name:
            return ""
        machine_definition = global_stack.getBottom()

        active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
        material_containers = [stack.findContainer(type="material") for stack in active_stacks]

        result = self._duplicateQualityOrQualityChangesForMachineType(quality_name, base_name,
                    QualityManager.getInstance().getParentMachineDefinition(machine_definition),
                    material_containers)
        return result[0].getName() if result else ""
Beispiel #23
0
    def createQualityChanges(self, base_name):
        global_stack = UM.Application.getInstance().getGlobalContainerStack()
        if not global_stack:
            return False

        active_quality_name = self._machine_manager.activeQualityName
        if active_quality_name == "":
            UM.Logger.log(
                "w",
                "No quality container found in stack %s, cannot create profile",
                global_stack.getId())
            return False

        self._machine_manager.blurSettings.emit()
        if base_name is None or base_name == "":
            base_name = active_quality_name
        unique_name = self._container_registry.uniqueName(base_name)

        # Go through the active stacks and create quality_changes containers from the user containers.
        for stack in cura.Settings.ExtruderManager.getInstance(
        ).getActiveGlobalAndExtruderStacks():
            user_container = stack.getTop()
            quality_container = stack.findContainer(type="quality")
            quality_changes_container = stack.findContainer(
                type="quality_changes")
            if not quality_container or not quality_changes_container:
                UM.Logger.log(
                    "w",
                    "No quality or quality changes container found in stack %s, ignoring it",
                    stack.getId())
                continue

            extruder_id = None if stack is global_stack else QualityManager.getInstance(
            ).getParentMachineDefinition(stack.getBottom()).getId()
            new_changes = self._createQualityChanges(
                quality_container, unique_name,
                UM.Application.getInstance().getGlobalContainerStack().
                getBottom(), extruder_id)
            self._performMerge(new_changes,
                               quality_changes_container,
                               clear_settings=False)
            self._performMerge(new_changes, user_container)

            self._container_registry.addContainer(new_changes)
            stack.replaceContainer(
                stack.getContainerIndex(quality_changes_container),
                new_changes)

        self._machine_manager.activeQualityChanged.emit()
        return True
Beispiel #24
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if not global_container_stack:
            return []

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)

        # Fetch the list of qualities
        quality_list =  QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                              ExtruderManager.getInstance().getActiveExtruderStacks())

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
        filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set]

        #Only display the global quality changes.
        #Otherwise you get multiple copies of every quality changes profile.
        #The actual profile switching goes by profile name (not ID), and as long as the names are consistent, switching to any of the profiles will cause all stacks to switch.
        filtered_quality_changes = list(filter(lambda quality_changes: quality_changes.getMetaDataEntry("extruder") is None, filtered_quality_changes))

        return filtered_quality_changes
Beispiel #25
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if not global_container_stack:
            return []

        # Fetch the list of quality changes.
        quality_manager = QualityManager.getInstance()
        machine_definition = quality_manager.getParentMachineDefinition(
            global_container_stack.getBottom())
        quality_changes_list = quality_manager.findAllQualityChangesForMachine(
            machine_definition)

        # Fetch the list of qualities
        quality_list = QualityManager.getInstance(
        ).findAllUsableQualitiesForMachineAndExtruders(
            global_container_stack,
            ExtruderManager.getInstance().getActiveExtruderStacks())

        # Filter the quality_change by the list of available quality_types
        quality_type_set = set(
            [x.getMetaDataEntry("quality_type") for x in quality_list])
        filtered_quality_changes = [
            qc for qc in quality_changes_list
            if qc.getMetaDataEntry("quality_type") in quality_type_set
        ]

        #Only display the global quality changes.
        #Otherwise you get multiple copies of every quality changes profile.
        #The actual profile switching goes by profile name (not ID), and as long as the names are consistent, switching to any of the profiles will cause all stacks to switch.
        filtered_quality_changes = list(
            filter(
                lambda quality_changes: quality_changes.getMetaDataEntry(
                    "extruder") is None, filtered_quality_changes))

        return filtered_quality_changes
Beispiel #26
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if global_container_stack is None:
            return []

        # Get the  list of extruders and place the selected extruder at the front of the list.
        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = extruder_manager.getActiveExtruderStacks()
        if active_extruder in extruder_stacks:
            extruder_stacks.remove(active_extruder)
            extruder_stacks = [active_extruder] + extruder_stacks

        # Fetch the list of useable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        return QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                                                         extruder_stacks)
Beispiel #27
0
    def _fetchInstanceContainers(self):
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if global_container_stack is None:
            return []

        # Get the  list of extruders and place the selected extruder at the front of the list.
        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = extruder_manager.getActiveExtruderStacks()
        if active_extruder in extruder_stacks:
            extruder_stacks.remove(active_extruder)
            extruder_stacks = [active_extruder] + extruder_stacks

        # Fetch the list of useable qualities across all extruders.
        # The actual list of quality profiles come from the first extruder in the extruder list.
        return QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                                                         extruder_stacks)
Beispiel #28
0
    def _createQualityChanges(self, quality_container, new_name, machine_definition, extruder_id):
        base_id = machine_definition.getId() if extruder_id is None else extruder_id

        # Create a new quality_changes container for the quality.
        quality_changes = InstanceContainer(self._createUniqueId(base_id, new_name))
        quality_changes.setName(new_name)
        quality_changes.addMetaDataEntry("type", "quality_changes")
        quality_changes.addMetaDataEntry("quality_type", quality_container.getMetaDataEntry("quality_type"))

        # If we are creating a container for an extruder, ensure we add that to the container
        if extruder_id is not None:
            quality_changes.addMetaDataEntry("extruder", extruder_id)

        # If the machine specifies qualities should be filtered, ensure we match the current criteria.
        if not machine_definition.getMetaDataEntry("has_machine_quality"):
            quality_changes.setDefinition(self._container_registry.findContainers(id = "fdmprinter")[0])
        else:
            quality_changes.setDefinition(QualityManager.getInstance().getParentMachineDefinition(machine_definition))
        return quality_changes
Beispiel #29
0
    def createQualityChanges(self, base_name):
        global_stack = Application.getInstance().getGlobalContainerStack()
        if not global_stack:
            return False

        active_quality_name = self._machine_manager.activeQualityName
        if active_quality_name == "":
            Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
            return False

        self._machine_manager.blurSettings.emit()
        if base_name is None or base_name == "":
            base_name = active_quality_name
        unique_name = self._container_registry.uniqueName(base_name)

        # Go through the active stacks and create quality_changes containers from the user containers.
        for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
            user_container = stack.getTop()
            quality_container = stack.findContainer(type = "quality")
            quality_changes_container = stack.findContainer(type = "quality_changes")
            if not quality_container or not quality_changes_container:
                Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
                continue

            extruder_id = None if stack is global_stack else QualityManager.getInstance().getParentMachineDefinition(stack.getBottom()).getId()
            new_changes = self._createQualityChanges(quality_container, unique_name,
                                                     Application.getInstance().getGlobalContainerStack().getBottom(),
                                                     extruder_id)
            self._performMerge(new_changes, quality_changes_container, clear_settings = False)
            self._performMerge(new_changes, user_container)

            self._container_registry.addContainer(new_changes)
            stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes)

        self._machine_manager.activeQualityChanged.emit()
        return True
Beispiel #30
0
    def _convertSavitarNodeToUMNode(self, savitar_node):
        um_node = SceneNode()
        transformation = self._createMatrixFromTransformationString(
            savitar_node.getTransformation())
        um_node.setTransformation(transformation)
        mesh_builder = MeshBuilder()

        data = numpy.fromstring(
            savitar_node.getMeshData().getFlatVerticesAsBytes(),
            dtype=numpy.float32)

        vertices = numpy.resize(data, (int(data.size / 3), 3))
        mesh_builder.setVertices(vertices)
        mesh_builder.calculateNormals(fast=True)
        mesh_data = mesh_builder.build()

        if len(mesh_data.getVertices()):
            um_node.setMeshData(mesh_data)

        for child in savitar_node.getChildren():
            child_node = self._convertSavitarNodeToUMNode(child)
            if child_node:
                um_node.addChild(child_node)

        if um_node.getMeshData() is None and len(um_node.getChildren()) == 0:
            return None

        settings = savitar_node.getSettings()

        # Add the setting override decorator, so we can add settings to this node.
        if settings:
            um_node.addDecorator(SettingOverrideDecorator())

            global_container_stack = Application.getInstance(
            ).getGlobalContainerStack()

            # Ensure the correct next container for the SettingOverride decorator is set.
            if global_container_stack:
                default_stack = ExtruderManager.getInstance().getExtruderStack(
                    0)

                if default_stack:
                    um_node.callDecoration("setActiveExtruder",
                                           default_stack.getId())

                # Get the definition & set it
                definition = QualityManager.getInstance(
                ).getParentMachineDefinition(
                    global_container_stack.getBottom())
                um_node.callDecoration("getStack").getTop().setDefinition(
                    definition.getId())

            setting_container = um_node.callDecoration("getStack").getTop()

            for key in settings:
                setting_value = settings[key]

                # Extruder_nr is a special case.
                if key == "extruder_nr":
                    extruder_stack = ExtruderManager.getInstance(
                    ).getExtruderStack(int(setting_value))
                    if extruder_stack:
                        um_node.callDecoration("setActiveExtruder",
                                               extruder_stack.getId())
                    else:
                        Logger.log("w",
                                   "Unable to find extruder in position %s",
                                   setting_value)
                    continue
                setting_container.setProperty(key, "value", setting_value)

        if len(um_node.getChildren()) > 0:
            group_decorator = GroupDecorator()
            um_node.addDecorator(group_decorator)
        um_node.setSelectable(True)
        if um_node.getMeshData():
            # Assuming that all nodes with mesh data are printable objects
            # affects (auto) slicing
            sliceable_decorator = SliceableObjectDecorator()
            um_node.addDecorator(sliceable_decorator)
        return um_node
Beispiel #31
0
    def _createNodeFromObject(self, object, name=""):
        node = SceneNode()
        node.setName(name)
        mesh_builder = MeshBuilder()
        vertex_list = []

        components = object.find(".//3mf:components", self._namespaces)
        if components:
            for component in components:
                id = component.get("objectid")
                new_object = self._root.find(
                    "./3mf:resources/3mf:object[@id='{0}']".format(id),
                    self._namespaces)
                new_node = self._createNodeFromObject(
                    new_object, self._base_name + "_" + str(id))
                node.addChild(new_node)
                transform = component.get("transform")
                if transform is not None:
                    new_node.setTransformation(
                        self._createMatrixFromTransformationString(transform))

        # for vertex in entry.mesh.vertices.vertex:
        for vertex in object.findall(".//3mf:vertex", self._namespaces):
            vertex_list.append(
                [vertex.get("x"),
                 vertex.get("y"),
                 vertex.get("z")])
            Job.yieldThread()

        xml_settings = list(object.findall(".//cura:setting",
                                           self._namespaces))

        # Add the setting override decorator, so we can add settings to this node.
        if xml_settings:
            node.addDecorator(SettingOverrideDecorator())

            global_container_stack = Application.getInstance(
            ).getGlobalContainerStack()
            # Ensure the correct next container for the SettingOverride decorator is set.
            if global_container_stack:
                multi_extrusion = global_container_stack.getProperty(
                    "machine_extruder_count", "value") > 1
                # Ensure that all extruder data is reset
                if not multi_extrusion:
                    default_stack_id = global_container_stack.getId()
                else:
                    default_stack = ExtruderManager.getInstance(
                    ).getExtruderStack(0)
                    if default_stack:
                        default_stack_id = default_stack.getId()
                    else:
                        default_stack_id = global_container_stack.getId()
                node.callDecoration("setActiveExtruder", default_stack_id)

                # Get the definition & set it
                definition = QualityManager.getInstance(
                ).getParentMachineDefinition(
                    global_container_stack.getBottom())
                node.callDecoration("getStack").getTop().setDefinition(
                    definition)

            setting_container = node.callDecoration("getStack").getTop()
            for setting in xml_settings:
                setting_key = setting.get("key")
                setting_value = setting.text

                # Extruder_nr is a special case.
                if setting_key == "extruder_nr":
                    extruder_stack = ExtruderManager.getInstance(
                    ).getExtruderStack(int(setting_value))
                    if extruder_stack:
                        node.callDecoration("setActiveExtruder",
                                            extruder_stack.getId())
                    else:
                        Logger.log("w",
                                   "Unable to find extruder in position %s",
                                   setting_value)
                    continue
                setting_container.setProperty(setting_key, "value",
                                              setting_value)

        if len(node.getChildren()) > 0:
            group_decorator = GroupDecorator()
            node.addDecorator(group_decorator)

        triangles = object.findall(".//3mf:triangle", self._namespaces)
        mesh_builder.reserveFaceCount(len(triangles))

        for triangle in triangles:
            v1 = int(triangle.get("v1"))
            v2 = int(triangle.get("v2"))
            v3 = int(triangle.get("v3"))

            mesh_builder.addFaceByPoints(
                vertex_list[v1][0], vertex_list[v1][1], vertex_list[v1][2],
                vertex_list[v2][0], vertex_list[v2][1], vertex_list[v2][2],
                vertex_list[v3][0], vertex_list[v3][1], vertex_list[v3][2])

            Job.yieldThread()

        # TODO: We currently do not check for normals and simply recalculate them.
        mesh_builder.calculateNormals(fast=True)
        mesh_builder.setFileName(name)
        mesh_data = mesh_builder.build()

        if len(mesh_data.getVertices()):
            node.setMeshData(mesh_data)

        node.setSelectable(True)
        return node
Beispiel #32
0
    def _recomputeItems(self):

        # Some globals that we can re-use.
        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if global_container_stack is None:
            return

        extruder_stacks = self._getOrderedExtruderStacksList()
        container_registry = ContainerRegistry.getInstance()

        # Get a list of usable/available qualities for this machine and material
        qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)

        unit = global_container_stack.getBottom().getProperty("layer_height", "unit")
        if not unit:
            unit = ""

        # group all quality items according to quality_types, so we know which profile suits the currently
        # active machine and material, and later yield the right ones.
        tmp_all_quality_items = OrderedDict()
        for item in super()._recomputeItems():

            profiles = container_registry.findContainersMetadata(id = item["id"])
            if not profiles or "quality_type" not in profiles[0]:
                quality_type = ""
            else:
                quality_type = profiles[0]["quality_type"]

            if quality_type not in tmp_all_quality_items:
                tmp_all_quality_items[quality_type] = {"suitable_container": None, "all_containers": []}

            tmp_all_quality_items[quality_type]["all_containers"].append(item)
            if tmp_all_quality_items[quality_type]["suitable_container"] is None:
                tmp_all_quality_items[quality_type]["suitable_container"] = item

        # reverse the ordering (finest first, coarsest last)
        all_quality_items = OrderedDict()
        for key in reversed(tmp_all_quality_items.keys()):
            all_quality_items[key] = tmp_all_quality_items[key]

        # First the suitable containers are set in the model
        containers = []
        for data_item in all_quality_items.values():
            suitable_item = data_item["suitable_container"]
            if suitable_item is not None:
                containers.append(suitable_item)

        # Once the suitable containers are collected, the rest of the containers are appended
        for data_item in all_quality_items.values():
            for item in data_item["all_containers"]:
                if item not in containers:
                    containers.append(item)

        # Now all the containers are set
        for item in containers:
            profile = container_registry.findContainers(id = item["id"])

            # When for some reason there is no profile container in the registry
            if not profile:
                self._setItemLayerHeight(item, "", "")
                item["available"] = False
                yield item
                continue

            profile = profile[0]

            # When there is a profile but it's an empty quality should. It's shown in the list (they are "Not Supported" profiles)
            if profile.getId() == "empty_quality":
                self._setItemLayerHeight(item, "", "")
                item["available"] = True
                yield item
                continue

            item["available"] = profile in qualities

            # Easy case: This profile defines its own layer height.
            if profile.hasProperty("layer_height", "value"):
                self._setItemLayerHeight(item, profile.getProperty("layer_height", "value"), unit)
                yield item
                continue

            machine_manager = Application.getInstance().getMachineManager()

            # Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
            quality_type = profile.getMetaDataEntry("quality_type", None)
            if quality_type:
                quality_results = machine_manager.determineQualityAndQualityChangesForQualityType(quality_type)
                for quality_result in quality_results:
                    if quality_result["stack"] is global_container_stack:
                        quality = quality_result["quality"]
                        break
                else:
                    # No global container stack in the results:
                    if quality_results:
                        # Take any of the extruders.
                        quality = quality_results[0]["quality"]
                    else:
                        quality = None
                if quality and quality.hasProperty("layer_height", "value"):
                    self._setItemLayerHeight(item, quality.getProperty("layer_height", "value"), unit)
                    yield item
                    continue

            # Quality has no value for layer height either. Get the layer height from somewhere lower in the stack.
            skip_until_container = global_container_stack.material
            if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer():  # No material in stack.
                skip_until_container = global_container_stack.variant
                if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer():  # No variant in stack.
                    skip_until_container = global_container_stack.getBottom()
            self._setItemLayerHeight(item, global_container_stack.getRawProperty("layer_height", "value", skip_until_container = skip_until_container.getId()), unit)  # Fall through to the currently loaded material.
            yield item
    def _recomputeItems(self):
        #Some globals that we can re-use.
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if global_container_stack is None:
            return

        # Detecting if the machine has multiple extrusion
        multiple_extrusion = global_container_stack.getProperty(
            "machine_extruder_count", "value") > 1
        # Get the list of extruders and place the selected extruder at the front of the list.
        extruder_manager = ExtruderManager.getInstance()
        active_extruder = extruder_manager.getActiveExtruderStack()
        extruder_stacks = extruder_manager.getActiveExtruderStacks()
        if multiple_extrusion:
            # Place the active extruder at the front of the list.
            # This is a workaround checking if there is an active_extruder or not before moving it to the front of the list.
            # Actually, when a printer has multiple extruders, should exist always an active_extruder. However, in some
            # cases the active_extruder is still None.
            if active_extruder in extruder_stacks:
                extruder_stacks.remove(active_extruder)
            new_extruder_stacks = []
            if active_extruder is not None:
                new_extruder_stacks = [active_extruder]
            extruder_stacks = new_extruder_stacks + extruder_stacks

        # Get a list of usable/available qualities for this machine and material
        qualities = QualityManager.getInstance(
        ).findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                       extruder_stacks)

        container_registry = ContainerRegistry.getInstance()
        machine_manager = Application.getInstance().getMachineManager()

        unit = global_container_stack.getBottom().getProperty(
            "layer_height", "unit")
        if not unit:
            unit = ""

        # group all quality items according to quality_types, so we know which profile suits the currently
        # active machine and material, and later yield the right ones.
        tmp_all_quality_items = OrderedDict()
        for item in super()._recomputeItems():
            profile = container_registry.findContainers(id=item["id"])
            quality_type = profile[0].getMetaDataEntry(
                "quality_type") if profile else ""

            if quality_type not in tmp_all_quality_items:
                tmp_all_quality_items[quality_type] = {
                    "suitable_container": None,
                    "all_containers": []
                }

            tmp_all_quality_items[quality_type]["all_containers"].append(item)
            if tmp_all_quality_items[quality_type][
                    "suitable_container"] is None:
                tmp_all_quality_items[quality_type][
                    "suitable_container"] = item

        # reverse the ordering (finest first, coarsest last)
        all_quality_items = OrderedDict()
        for key in reversed(tmp_all_quality_items.keys()):
            all_quality_items[key] = tmp_all_quality_items[key]

        # First the suitable containers are set in the model
        containers = []
        for data_item in all_quality_items.values():
            suitable_item = data_item["suitable_container"]
            if suitable_item is not None:
                containers.append(suitable_item)

        # Once the suitable containers are collected, the rest of the containers are appended
        for data_item in all_quality_items.values():
            for item in data_item["all_containers"]:
                if item not in containers:
                    containers.append(item)

        # Now all the containers are set
        for item in containers:
            profile = container_registry.findContainers(id=item["id"])
            if not profile:
                self._setItemLayerHeight(item, "", unit)
                item["available"] = False
                yield item
                continue

            profile = profile[0]
            item["available"] = profile in qualities

            # Easy case: This profile defines its own layer height.
            if profile.hasProperty("layer_height", "value"):
                self._setItemLayerHeight(
                    item, profile.getProperty("layer_height", "value"), unit)
                yield item
                continue

            # Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
            quality_type = profile.getMetaDataEntry("quality_type", None)
            if quality_type:
                quality_results = machine_manager.determineQualityAndQualityChangesForQualityType(
                    quality_type)
                for quality_result in quality_results:
                    if quality_result["stack"] is global_container_stack:
                        quality = quality_result["quality"]
                        break
                else:  #No global container stack in the results:
                    if quality_results:
                        quality = quality_results[0][
                            "quality"]  #Take any of the extruders.
                    else:
                        quality = None
                if quality and quality.hasProperty("layer_height", "value"):
                    self._setItemLayerHeight(
                        item, quality.getProperty("layer_height", "value"),
                        unit)
                    yield item
                    continue

            #Quality has no value for layer height either. Get the layer height from somewhere lower in the stack.
            skip_until_container = global_container_stack.material
            if not skip_until_container or skip_until_container == ContainerRegistry.getInstance(
            ).getEmptyInstanceContainer():  #No material in stack.
                skip_until_container = global_container_stack.variant
                if not skip_until_container or skip_until_container == ContainerRegistry.getInstance(
                ).getEmptyInstanceContainer():  #No variant in stack.
                    skip_until_container = global_container_stack.getBottom()
            self._setItemLayerHeight(
                item,
                global_container_stack.getRawProperty(
                    "layer_height",
                    "value",
                    skip_until_container=skip_until_container.getId()),
                unit)  # Fall through to the currently loaded material.
            yield item
Beispiel #34
0
    def _createNodeFromObject(self, object, name = ""):
        node = SceneNode()
        node.setName(name)
        mesh_builder = MeshBuilder()
        vertex_list = []

        components = object.find(".//3mf:components", self._namespaces)
        if components:
            for component in components:
                id = component.get("objectid")
                new_object = self._root.find("./3mf:resources/3mf:object[@id='{0}']".format(id), self._namespaces)
                new_node = self._createNodeFromObject(new_object, self._base_name + "_" + str(id))
                node.addChild(new_node)
                transform = component.get("transform")
                if transform is not None:
                    new_node.setTransformation(self._createMatrixFromTransformationString(transform))

        # for vertex in entry.mesh.vertices.vertex:
        for vertex in object.findall(".//3mf:vertex", self._namespaces):
            vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
            Job.yieldThread()

        xml_settings = list(object.findall(".//cura:setting", self._namespaces))

        # Add the setting override decorator, so we can add settings to this node.
        if xml_settings:
            node.addDecorator(SettingOverrideDecorator())

            global_container_stack = Application.getInstance().getGlobalContainerStack()
            # Ensure the correct next container for the SettingOverride decorator is set.
            if global_container_stack:
                multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
                # Ensure that all extruder data is reset
                if not multi_extrusion:
                    default_stack_id = global_container_stack.getId()
                else:
                    default_stack = ExtruderManager.getInstance().getExtruderStack(0)
                    if default_stack:
                        default_stack_id = default_stack.getId()
                    else:
                        default_stack_id = global_container_stack.getId()
                node.callDecoration("setActiveExtruder", default_stack_id)

                # Get the definition & set it
                definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
                node.callDecoration("getStack").getTop().setDefinition(definition)

            setting_container = node.callDecoration("getStack").getTop()
            for setting in xml_settings:
                setting_key = setting.get("key")
                setting_value = setting.text

                # Extruder_nr is a special case.
                if setting_key == "extruder_nr":
                    extruder_stack = ExtruderManager.getInstance().getExtruderStack(int(setting_value))
                    if extruder_stack:
                        node.callDecoration("setActiveExtruder", extruder_stack.getId())
                    else:
                        Logger.log("w", "Unable to find extruder in position %s", setting_value)
                    continue
                setting_container.setProperty(setting_key,"value", setting_value)

        if len(node.getChildren()) > 0:
            group_decorator = GroupDecorator()
            node.addDecorator(group_decorator)

        triangles = object.findall(".//3mf:triangle", self._namespaces)
        mesh_builder.reserveFaceCount(len(triangles))

        for triangle in triangles:
            v1 = int(triangle.get("v1"))
            v2 = int(triangle.get("v2"))
            v3 = int(triangle.get("v3"))

            mesh_builder.addFaceByPoints(vertex_list[v1][0], vertex_list[v1][1], vertex_list[v1][2],
                                         vertex_list[v2][0], vertex_list[v2][1], vertex_list[v2][2],
                                         vertex_list[v3][0], vertex_list[v3][1], vertex_list[v3][2])

            Job.yieldThread()

        # TODO: We currently do not check for normals and simply recalculate them.
        mesh_builder.calculateNormals()
        mesh_builder.setFileName(name)
        mesh_data = mesh_builder.build()

        if len(mesh_data.getVertices()):
            node.setMeshData(mesh_data)

        node.setSelectable(True)
        return node
Beispiel #35
0
    def _recomputeItems(self):
        # Some globals that we can re-use.
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if global_container_stack is None:
            return

        extruder_stacks = self._getOrderedExtruderStacksList()
        container_registry = ContainerRegistry.getInstance()

        # Get a list of usable/available qualities for this machine and material
        qualities = QualityManager.getInstance(
        ).findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
                                                       extruder_stacks)

        unit = global_container_stack.getBottom().getProperty(
            "layer_height", "unit")
        if not unit:
            unit = ""

        # group all quality items according to quality_types, so we know which profile suits the currently
        # active machine and material, and later yield the right ones.
        tmp_all_quality_items = OrderedDict()
        for item in super()._recomputeItems():
            profiles = container_registry.findContainersMetadata(id=item["id"])
            if not profiles or "quality_type" not in profiles[0]:
                quality_type = ""
            else:
                quality_type = profiles[0]["quality_type"]

            if quality_type not in tmp_all_quality_items:
                tmp_all_quality_items[quality_type] = {
                    "suitable_container": None,
                    "all_containers": []
                }

            tmp_all_quality_items[quality_type]["all_containers"].append(item)
            if tmp_all_quality_items[quality_type][
                    "suitable_container"] is None:
                tmp_all_quality_items[quality_type][
                    "suitable_container"] = item

        # reverse the ordering (finest first, coarsest last)
        all_quality_items = OrderedDict()
        for key in reversed(tmp_all_quality_items.keys()):
            all_quality_items[key] = tmp_all_quality_items[key]

        # First the suitable containers are set in the model
        containers = []
        for data_item in all_quality_items.values():
            suitable_item = data_item["suitable_container"]
            if suitable_item is not None:
                containers.append(suitable_item)

        # Once the suitable containers are collected, the rest of the containers are appended
        for data_item in all_quality_items.values():
            for item in data_item["all_containers"]:
                if item not in containers:
                    containers.append(item)

        # Now all the containers are set
        for item in containers:
            profile = container_registry.findContainers(id=item["id"])

            # When for some reason there is no profile container in the registry
            if not profile:
                self._setItemLayerHeight(item, "", "")
                item["available"] = False
                yield item
                continue

            profile = profile[0]

            # When there is a profile but it's an empty quality should. It's shown in the list (they are "Not Supported" profiles)
            if profile.getId() == "empty_quality":
                self._setItemLayerHeight(item, "", "")
                item["available"] = True
                yield item
                continue

            item["available"] = profile in qualities

            # Easy case: This profile defines its own layer height.
            if profile.hasProperty("layer_height", "value"):
                self._setItemLayerHeight(
                    item, profile.getProperty("layer_height", "value"), unit)
                yield item
                continue

            machine_manager = Application.getInstance().getMachineManager()

            # Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
            quality_type = profile.getMetaDataEntry("quality_type", None)
            if quality_type:
                quality_results = machine_manager.determineQualityAndQualityChangesForQualityType(
                    quality_type)
                for quality_result in quality_results:
                    if quality_result["stack"] is global_container_stack:
                        quality = quality_result["quality"]
                        break
                else:
                    # No global container stack in the results:
                    if quality_results:
                        # Take any of the extruders.
                        quality = quality_results[0]["quality"]
                    else:
                        quality = None
                if quality and quality.hasProperty("layer_height", "value"):
                    self._setItemLayerHeight(
                        item, quality.getProperty("layer_height", "value"),
                        unit)
                    yield item
                    continue

            # Quality has no value for layer height either. Get the layer height from somewhere lower in the stack.
            skip_until_container = global_container_stack.material
            if not skip_until_container or skip_until_container == ContainerRegistry.getInstance(
            ).getEmptyInstanceContainer():  # No material in stack.
                skip_until_container = global_container_stack.variant
                if not skip_until_container or skip_until_container == ContainerRegistry.getInstance(
                ).getEmptyInstanceContainer():  # No variant in stack.
                    skip_until_container = global_container_stack.getBottom()
            self._setItemLayerHeight(
                item,
                global_container_stack.getRawProperty(
                    "layer_height",
                    "value",
                    skip_until_container=skip_until_container.getId()),
                unit)  # Fall through to the currently loaded material.
            yield item
Beispiel #36
0
    def _convertSavitarNodeToUMNode(self, savitar_node):
        um_node = SceneNode()
        transformation = self._createMatrixFromTransformationString(savitar_node.getTransformation())
        um_node.setTransformation(transformation)
        mesh_builder = MeshBuilder()

        data = numpy.fromstring(savitar_node.getMeshData().getFlatVerticesAsBytes(), dtype=numpy.float32)

        vertices = numpy.resize(data, (int(data.size / 3), 3))
        mesh_builder.setVertices(vertices)
        mesh_builder.calculateNormals(fast=True)
        mesh_data = mesh_builder.build()

        if len(mesh_data.getVertices()):
            um_node.setMeshData(mesh_data)

        for child in savitar_node.getChildren():
            child_node = self._convertSavitarNodeToUMNode(child)
            if child_node:
                um_node.addChild(child_node)

        if um_node.getMeshData() is None and len(um_node.getChildren()) == 0:
            return None

        settings = savitar_node.getSettings()

        # Add the setting override decorator, so we can add settings to this node.
        if settings:
            um_node.addDecorator(SettingOverrideDecorator())

            global_container_stack = Application.getInstance().getGlobalContainerStack()
            # Ensure the correct next container for the SettingOverride decorator is set.
            if global_container_stack:
                multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1

                # Ensure that all extruder data is reset
                if not multi_extrusion:
                    default_stack_id = global_container_stack.getId()
                else:
                    default_stack = ExtruderManager.getInstance().getExtruderStack(0)
                    if default_stack:
                        default_stack_id = default_stack.getId()
                    else:
                        default_stack_id = global_container_stack.getId()
                um_node.callDecoration("setActiveExtruder", default_stack_id)

                # Get the definition & set it
                definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
                um_node.callDecoration("getStack").getTop().setDefinition(definition)

            setting_container = um_node.callDecoration("getStack").getTop()

            for key in settings:
                setting_value = settings[key]

                # Extruder_nr is a special case.
                if key == "extruder_nr":
                    extruder_stack = ExtruderManager.getInstance().getExtruderStack(int(setting_value))
                    if extruder_stack:
                        um_node.callDecoration("setActiveExtruder", extruder_stack.getId())
                    else:
                        Logger.log("w", "Unable to find extruder in position %s", setting_value)
                    continue
                setting_container.setProperty(key,"value", setting_value)

        if len(um_node.getChildren()) > 0:
            group_decorator = GroupDecorator()
            um_node.addDecorator(group_decorator)
        um_node.setSelectable(True)
        if um_node.getMeshData():
            # Assuming that all nodes with mesh data are printable objects
            # affects (auto) slicing
            sliceable_decorator = SliceableObjectDecorator()
            um_node.addDecorator(sliceable_decorator)
        return um_node
Beispiel #37
0
 def _getFilteredContainers(self, **kwargs):
     return QualityManager.getInstance()._getFilteredContainers(**kwargs)
Beispiel #38
0
    def exportProfile(self, instance_ids, file_name, file_type):
        # Parse the fileType to deduce what plugin can save the file format.
        # fileType has the format "<description> (*.<extension>)"
        split = file_type.rfind(
            " (*."
        )  # Find where the description ends and the extension starts.
        if split < 0:  # Not found. Invalid format.
            Logger.log("e", "Invalid file format identifier %s", file_type)
            return
        description = file_type[:split]
        extension = file_type[split + 4:-1]  # Leave out the " (*." and ")".
        if not file_name.endswith(
                "." + extension
        ):  # Auto-fill the extension if the user did not provide any.
            file_name += "." + extension

        # On Windows, QML FileDialog properly asks for overwrite confirm, but not on other platforms, so handle those ourself.
        if not Platform.isWindows():
            if os.path.exists(file_name):
                result = QMessageBox.question(
                    None, catalog.i18nc("@title:window",
                                        "File Already Exists"),
                    catalog.i18nc(
                        "@label Don't translate the XML tag <filename>!",
                        "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?"
                    ).format(file_name))
                if result == QMessageBox.No:
                    return
        found_containers = []
        extruder_positions = []
        for instance_id in instance_ids:
            containers = ContainerRegistry.getInstance(
            ).findInstanceContainers(id=instance_id)
            if containers:
                found_containers.append(containers[0])

                # Determine the position of the extruder of this container
                extruder_id = containers[0].getMetaDataEntry("extruder", "")
                if extruder_id == "":
                    # Global stack
                    extruder_positions.append(-1)
                else:
                    extruder_containers = ContainerRegistry.getInstance(
                    ).findDefinitionContainersMetadata(id=extruder_id)
                    if extruder_containers:
                        extruder_positions.append(
                            int(extruder_containers[0].get("position", 0)))
                    else:
                        extruder_positions.append(0)
        # Ensure the profiles are always exported in order (global, extruder 0, extruder 1, ...)
        found_containers = [
            containers
            for (positions, containers
                 ) in sorted(zip(extruder_positions, found_containers))
        ]
        base_containers = []
        quality_manager = QualityManager.getInstance()

        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        global_machine_definition = quality_manager.getParentMachineDefinition(
            global_container_stack.getBottom())
        for container in found_containers:
            if container.getMetaDataEntry("type") == "quality_changes":
                material = ContainerRegistry.getInstance(
                ).findInstanceContainers(
                    id=container.getMetaDataEntry("material"))
                if len(material) > 0:
                    base_container = quality_manager.findQualityByQualityType(
                        container.getMetaDataEntry("quality_type"),
                        global_machine_definition, [material[0].getMetaData()])
                    if base_container:
                        c = copy.deepcopy(base_container)
                        c.setMetaDataEntry("id", "base/" + container.id)
                        base_containers.append(c)
        found_containers.extend(base_containers)

        profile_writer = self._findProfileWriter(extension, description)

        try:
            success = profile_writer.write(file_name, found_containers)
        except Exception as e:
            Logger.log("e", "Failed to export profile to %s: %s", file_name,
                       str(e))
            m = Message(catalog.i18nc(
                "@info:status Don't translate the XML tags <filename> or <message>!",
                "Failed to export profile to <filename>{0}</filename>: <message>{1}</message>",
                file_name, str(e)),
                        lifetime=0,
                        title=catalog.i18nc("@info:title", "Error"))
            m.show()
            return
        if not success:
            Logger.log(
                "w",
                "Failed to export profile to %s: Writer plugin reported failure.",
                file_name)
            m = Message(catalog.i18nc(
                "@info:status Don't translate the XML tag <filename>!",
                "Failed to export profile to <filename>{0}</filename>: Writer plugin reported failure.",
                file_name),
                        lifetime=0,
                        title=catalog.i18nc("@info:title", "Error"))
            m.show()
            return
        m = Message(catalog.i18nc(
            "@info:status Don't translate the XML tag <filename>!",
            "Exported profile to <filename>{0}</filename>", file_name),
                    title=catalog.i18nc("@info:title", "Export succeeded"))
        m.show()
Beispiel #39
0
 def _getFilteredContainers(self, **kwargs):
     return QualityManager.getInstance()._getFilteredContainers(**kwargs)