Ejemplo n.º 1
0
    def addContainer(self, container: ContainerInterface) -> None:
        containers = self.findContainers(container_type = container.__class__, id = container.getId())
        if containers:
            Logger.log("w", "Container of type %s and id %s already added", repr(container.__class__), container.getId())
            return

        if hasattr(container, "metaDataChanged"):
            container.metaDataChanged.connect(self._onContainerMetaDataChanged)

        self._containers.append(container)
        self._id_container_cache[container.getId()] = container
        self._clearQueryCache()
        self.containerAdded.emit(container)
Ejemplo n.º 2
0
    def addContainer(self, container: ContainerInterface) -> None:
        containers = self.findContainers(container_type = container.__class__, id = container.getId())
        if containers:
            Logger.log("w", "Container of type %s and id %s already added", repr(container.__class__), container.getId())
            return

        if hasattr(container, "metaDataChanged"):
            container.metaDataChanged.connect(self._onContainerMetaDataChanged)

        self._containers.append(container)
        self._id_container_cache[container.getId()] = container
        self._clearQueryCache()
        self.containerAdded.emit(container)
Ejemplo n.º 3
0
    def addContainer(self, container: ContainerInterface) -> None:
        containers = self.findContainers(container_type = container.__class__, id = container.getId())
        if containers:
            Logger.log("w", "Container of type %s and id %s already added", repr(container.__class__), container.getId())
            return

        if hasattr(container, "metaDataChanged"):
            # Since queries are based on metadata, we need to make sure to clear the cache when a container's metadata changes.
            container.metaDataChanged.connect(self._clearQueryCache)

        self._containers.append(container)
        self._id_container_cache[container.getId()] = container
        self._clearQueryCache()
        self.containerAdded.emit(container)
Ejemplo n.º 4
0
    def _onMetadataChanged(self, container: ContainerInterface,
                           **kwargs: Any) -> None:
        """Triggered when any metadata changed in any container, but only handles it when the metadata of this node is
        changed.

        :param container: The container whose metadata changed.
        :param kwargs: Key-word arguments provided when changing the metadata. These are ignored. As far as I know they
        are never provided to this call.
        """

        if container.getId() != self.container_id:
            return

        new_metadata = container.getMetaData()
        old_base_file = self.base_file
        if new_metadata["base_file"] != old_base_file:
            self.base_file = new_metadata["base_file"]
            if old_base_file in self.variant.materials:  # Move in parent node.
                del self.variant.materials[old_base_file]
            self.variant.materials[self.base_file] = self

        old_material_type = self.material_type
        self.material_type = new_metadata["material"]
        old_guid = self.guid
        self.guid = new_metadata["GUID"]
        if self.base_file != old_base_file or self.material_type != old_material_type or self.guid != old_guid:  # List of quality profiles could've changed.
            self.qualities = {}
            self._loadAll()  # Re-load the quality profiles for this node.
        self.materialChanged.emit(self)
Ejemplo n.º 5
0
    def _materialAdded(self, container: ContainerInterface) -> None:
        if container.getMetaDataEntry("type") != "material":
            return  # Not interested.
        if not self.machine.has_materials:
            return  # We won't add any materials.
        material_definition = container.getMetaDataEntry("definition")

        base_file = container.getMetaDataEntry("base_file")
        if base_file in self.machine.exclude_materials:
            return  # Material is forbidden for this printer.
        if base_file not in self.materials:  # Completely new base file. Always better than not having a file as long as it matches our set-up.
            if material_definition != "fdmprinter" and material_definition != self.machine.container_id:
                return
            material_variant = container.getMetaDataEntry("variant_name", "empty")
            if material_variant != "empty" and material_variant != self.variant_name:
                return
        else:  # We already have this base profile. Replace the base profile if the new one is more specific.
            new_definition = container.getMetaDataEntry("definition")
            if new_definition == "fdmprinter":
                return  # Just as unspecific or worse.
            if new_definition != self.machine.container_id:
                return  # Doesn't match this set-up.
            original_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = self.materials[base_file].container_id)[0]
            original_variant = original_metadata.get("variant_name", "empty")
            if original_variant != "empty" or container.getMetaDataEntry("variant_name", "empty") == "empty":
                return  # Original was already specific or just as unspecific as the new one.

        if "empty_material" in self.materials:
            del self.materials["empty_material"]
        self.materials[base_file] = MaterialNode(container.getId(), variant = self)
        self.materials[base_file].materialChanged.connect(self.materialsChanged)
        self.materialsChanged.emit(self.materials[base_file])
Ejemplo n.º 6
0
    def replaceContainer(self,
                         index: int,
                         container: ContainerInterface,
                         postpone_emit: bool = False) -> None:
        """Overridden from ContainerStack

        Replaces the container at the specified index with another container.
        This version performs checks to make sure the new container has the expected metadata and type.

        :throws Exception.InvalidContainerError Raised when trying to replace a container with a container that has an incorrect type.
        """

        expected_type = _ContainerIndexes.IndexTypeMap[index]
        if expected_type == "definition":
            if not isinstance(container, DefinitionContainer):
                raise Exceptions.InvalidContainerError(
                    "Cannot replace container at index {index} with a container that is not a DefinitionContainer"
                    .format(index=index))
        elif container != self._empty_instance_container and container.getMetaDataEntry(
                "type") != expected_type:
            raise Exceptions.InvalidContainerError(
                "Cannot replace container at index {index} with a container that is not of {type} type, but {actual_type} type."
                .format(index=index,
                        type=expected_type,
                        actual_type=container.getMetaDataEntry("type")))

        current_container = self._containers[index]
        if current_container.getId() == container.getId():
            return

        super().replaceContainer(index, container, postpone_emit)
Ejemplo n.º 7
0
    def _materialAdded(self, container: ContainerInterface) -> None:
        if container.getMetaDataEntry("type") != "material":
            return  # Not interested.
        if not ContainerRegistry.getInstance().findContainersMetadata(
                id=container.getId()):
            # CURA-6889
            # containerAdded and removed signals may be triggered in the next event cycle. If a container gets added
            # and removed in the same event cycle, in the next cycle, the connections should just ignore the signals.
            # The check here makes sure that the container in the signal still exists.
            Logger.log(
                "d",
                "Got container added signal for container [%s] but it no longer exists, do nothing.",
                container.getId())
            return
        if not self.machine.has_materials:
            return  # We won't add any materials.
        material_definition = container.getMetaDataEntry("definition")

        base_file = container.getMetaDataEntry("base_file")
        if base_file in self.machine.exclude_materials:
            return  # Material is forbidden for this printer.
        if base_file not in self.materials:  # Completely new base file. Always better than not having a file as long as it matches our set-up.
            if material_definition != "fdmprinter" and material_definition != self.machine.container_id:
                return
            material_variant = container.getMetaDataEntry("variant_name")
            if material_variant is not None and material_variant != self.variant_name:
                return
        else:  # We already have this base profile. Replace the base profile if the new one is more specific.
            new_definition = container.getMetaDataEntry("definition")
            if new_definition == "fdmprinter":
                return  # Just as unspecific or worse.
            material_variant = container.getMetaDataEntry("variant_name")
            if new_definition != self.machine.container_id or material_variant != self.variant_name:
                return  # Doesn't match this set-up.
            original_metadata = ContainerRegistry.getInstance(
            ).findContainersMetadata(
                id=self.materials[base_file].container_id)[0]
            if "variant_name" in original_metadata or material_variant is None:
                return  # Original was already specific or just as unspecific as the new one.

        if "empty_material" in self.materials:
            del self.materials["empty_material"]
        self.materials[base_file] = MaterialNode(container.getId(),
                                                 variant=self)
        self.materials[base_file].materialChanged.connect(
            self.materialsChanged)
        self.materialsChanged.emit(self.materials[base_file])
Ejemplo n.º 8
0
 def _onRemoved(self, container: ContainerInterface) -> None:
     if container.getId() == self.container_id:
         # Remove myself from my parent.
         if self.base_file in self.variant.materials:
             del self.variant.materials[self.base_file]
             if not self.variant.materials:
                 self.variant.materials["empty_material"] = MaterialNode("empty_material", variant = self.variant)
         self.materialChanged.emit(self)
Ejemplo n.º 9
0
    def replaceContainer(self, index: int, container: ContainerInterface, postpone_emit: bool = False) -> None:
        expected_type = _ContainerIndexes.IndexTypeMap[index]
        if expected_type == "definition":
            if not isinstance(container, DefinitionContainer):
                raise Exceptions.InvalidContainerError("Cannot replace container at index {index} with a container that is not a DefinitionContainer".format(index = index))
        elif container != self._empty_instance_container and container.getMetaDataEntry("type") != expected_type:
            raise Exceptions.InvalidContainerError("Cannot replace container at index {index} with a container that is not of {type} type, but {actual_type} type.".format(index = index, type = expected_type, actual_type = container.getMetaDataEntry("type")))

        current_container = self._containers[index]
        if current_container.getId() == container.getId():
            return

        super().replaceContainer(index, container, postpone_emit)
Ejemplo n.º 10
0
    def _onRemoved(self, container: ContainerInterface) -> None:
        """Triggered when any container is removed, but only handles it when the container is removed that this node
        represents.

        :param container: The container that was allegedly removed.
        """

        if container.getId() == self.container_id:
            # Remove myself from my parent.
            if self.base_file in self.variant.materials:
                del self.variant.materials[self.base_file]
                if not self.variant.materials:
                    self.variant.materials["empty_material"] = MaterialNode(
                        "empty_material", variant=self.variant)
            self.materialChanged.emit(self)
Ejemplo n.º 11
0
    def addContainer(self, container: ContainerInterface) -> None:
        container_id = container.getId()
        if container_id in self._containers:
            Logger.log("w", "Container with ID %s was already added.", container_id)
            return

        if hasattr(container, "metaDataChanged"):
            container.metaDataChanged.connect(self._onContainerMetaDataChanged)

        self.metadata[container_id] = container.getMetaData()
        self._containers[container_id] = container
        if container_id not in self.source_provider:
            self.source_provider[container_id] = None #Added during runtime.
        self._clearQueryCacheByContainer(container)
        self.containerAdded.emit(container)
        Logger.log("d", "Container [%s] added.", container_id)
Ejemplo n.º 12
0
    def _onContainerAdded(self, container: ContainerInterface) -> None:
        # We don't have all the machines loaded in the beginning, so in order to add the missing extruder stack
        # for single extrusion machines, we subscribe to the containerAdded signal, and whenever a global stack
        # is added, we check to see if an extruder stack needs to be added.
        if not isinstance(container, ContainerStack
                          ) or container.getMetaDataEntry("type") != "machine":
            return

        machine_extruder_trains = container.getMetaDataEntry(
            "machine_extruder_trains")
        if machine_extruder_trains is not None and machine_extruder_trains != {
                "0": "fdmextruder"
        }:
            return

        extruder_stacks = self.findContainerStacks(type="extruder_train",
                                                   machine=container.getId())
        if not extruder_stacks:
            self.addExtruderStackForSingleExtrusionMachine(
                container, "fdmextruder")
Ejemplo n.º 13
0
    def addContainer(self, container: ContainerInterface) -> None:
        container_id = container.getId()
        if container_id in self._containers:
            return

        if hasattr(container, "metaDataChanged"):
            container.metaDataChanged.connect(self._onContainerMetaDataChanged)

        self.metadata[container_id] = container.getMetaData()
        self._containers[container_id] = container
        if container_id not in self.source_provider:
            self.source_provider[container_id] = None #Added during runtime.
        self._clearQueryCacheByContainer(container)

        # containerAdded is a custom signal and can trigger direct calls to its subscribers. This should be avoided
        # because with the direct calls, the subscribers need to know everything about what it tries to do to avoid
        # triggering this signal again, which eventually can end up exceeding the max recursion limit.
        # We avoid the direct calls here to make sure that the subscribers do not need to take into account any max
        # recursion problem.
        self._application.callLater(self.containerAdded.emit, container)
Ejemplo n.º 14
0
    def _onMetadataChanged(self, container: ContainerInterface, **kwargs: Any) -> None:
        if container.getId() != self.container_id:
            return

        new_metadata = container.getMetaData()
        old_base_file = self.base_file
        if new_metadata["base_file"] != old_base_file:
            self.base_file = new_metadata["base_file"]
            if old_base_file in self.variant.materials:  # Move in parent node.
                del self.variant.materials[old_base_file]
            self.variant.materials[self.base_file] = self

        old_material_type = self.material_type
        self.material_type = new_metadata["material"]
        old_guid = self.guid
        self.guid = new_metadata["GUID"]
        if self.base_file != old_base_file or self.material_type != old_material_type or self.guid != old_guid:  # List of quality profiles could've changed.
            self.qualities = {}
            self._loadAll()  # Re-load the quality profiles for this node.
        self.materialChanged.emit(self)
Ejemplo n.º 15
0
    def addContainer(self, container: ContainerInterface) -> None:
        container_id = container.getId()
        if container_id in self._containers:
            Logger.log("w", "Container with ID %s was already added.", container_id)
            return

        if hasattr(container, "metaDataChanged"):
            container.metaDataChanged.connect(self._onContainerMetaDataChanged)

        self.metadata[container_id] = container.getMetaData()
        self._containers[container_id] = container
        if container_id not in self.source_provider:
            self.source_provider[container_id] = None #Added during runtime.
        self._clearQueryCacheByContainer(container)
        Logger.log("d", "Container [%s] added.", container_id)

        # containerAdded is a custom signal and can trigger direct calls to its subscribers. This should be avoided
        # because with the direct calls, the subscribers need to know everything about what it tries to do to avoid
        # triggering this signal again, which eventually can end up exceeding the max recursion limit.
        # We avoid the direct calls here to make sure that the subscribers do not need to take into account any max
        # recursion problem.
        self._application.callLater(self.containerAdded.emit, container)
Ejemplo n.º 16
0
    def addContainer(self, container: ContainerInterface) -> None:
        # Note: Intentional check with type() because we want to ignore subclasses
        if type(container) == ContainerStack:
            container = self._convertContainerStack(
                cast(ContainerStack, container))

        if isinstance(container,
                      InstanceContainer) and type(container) != type(
                          self.getEmptyInstanceContainer()):
            # Check against setting version of the definition.
            required_setting_version = cura.CuraApplication.CuraApplication.SettingVersion
            actual_setting_version = int(
                container.getMetaDataEntry("setting_version", default=0))
            if required_setting_version != actual_setting_version:
                Logger.log(
                    "w",
                    "Instance container {container_id} is outdated. Its setting version is {actual_setting_version} but it should be {required_setting_version}."
                    .format(container_id=container.getId(),
                            actual_setting_version=actual_setting_version,
                            required_setting_version=required_setting_version))
                return  # Don't add.

        super().addContainer(container)