Beispiel #1
0
    def get_root_from_file(self, file_name, flatten_hierarchy=False):
        """
        :param file_name: the kiko file path
        :param flatten_hierarchy: flattens the hierarchy stored inside the file
        """
        k_file = KikoFile(file_name)
        k_file.parse()

        d = deserializers.DeserializerManager.get_deserializer(k_file.version,
                                                               self._facade)
        return d.get_root_from_data(k_file.data,
                                    flatten_hierarchy=flatten_hierarchy)
Beispiel #2
0
    def _load_kiko_file(self, path):
        if path != self._kiko_file_path:
            self._kiko_file_path = path

            k_file = KikoFile(self._kiko_file_path)
            k_file.parse()

            d = deserializers.DeserializerManager.get_deserializer(
                                        k_file.version, self._manager.facade)
            root = d.get_root_from_data(k_file.data)

            self._import_button.setEnabled(True)
            self._tab_widget.setEnabled(True)

            self._preview.file = k_file

            self._frame_range.set_range(root.start_frame, root.end_frame)
            self._mapping.set_root(root)
Beispiel #3
0
    def file(self, kiko_file):
        if isinstance(kiko_file, KikoFile):
            self._static_image_only = kiko_file.num_images == 0
            self._kiko_file = kiko_file
        else:
            self._static_image_only = (kiko_file is None or
                                   not kiko_file.endswith(KIKO_FILE_EXTENSION))

            if not self._static_image_only:
                self._kiko_file = KikoFile(kiko_file)
                self._kiko_file.parse()

        self._static_image = QtGui.QImage()
        if self._static_image_only:
            self._static_image.load(get_image('kiko.jpg'))
        else:
            self._scrubbing_line_position = 5

            if self._kiko_file.num_images > 0:
                self._static_image.loadFromData(self._kiko_file.get_image(0))

                self._timer = QtCore.QTimer(self)
                self._timer.setInterval(1000 / KIKO_PREVIEW_FPS)
                self._timer.timeout.connect(self._next_frame)
            else:
                self._static_image.load(get_image('kiko.jpg'))
                self._static_image_only = True

        self.setMouseTracking(not self._static_image_only)

        self._current_image = self._static_image
        self.setMaximumWidth(self._static_image.width())
        self.setMaximumHeight(self._static_image.height())

        if not self._current_image.isNull():
            self.setMinimumHeight(self.width() / self.aspect_ratio)

        if self._play_by_default:
            self.play()
        else:
            self.repaint()
Beispiel #4
0
    def _export_button_clicked(self):
        path = self._file_path.text()
        if not os.path.exists(os.path.dirname(path)):
            QtWidgets.QMessageBox.critical(self, "Error", "Invalid file path.")
            return

        facade = self._manager.facade
        if not facade.get_selection():
            QtWidgets.QMessageBox.critical(self, "Error", "Please selected "
                                           "something and retry.")
            return

        f_name = self._sanitise_file_name(path)

        start_frame, end_frame = self._get_start_end_frame()
        selected_operators = self._get_selected_operators()

        self._manager.export_to_file(f_name, operators=selected_operators,
                                keep_previous_images=False,
                                hierarchy=self._hierarchy.isChecked(),
                                start_frame=start_frame, end_frame=end_frame,
                                force_op_evaluation=self._force_all.isChecked())

        if self._data_export.isChecked():
            QtWidgets.QMessageBox.information(self, "Success!", "KB file "
                                                                "exported "
                                                                "successfully!")
            return

        sample = int(self._image_sampling.text())
        start, end = self._image_frame_range.get_range()
        images = facade.generate_image_sequence(
                        self._image_source.currentText(), start, end, sample)
        if not images:
            raise InvalidOperation("Could not generate images")

        if self._app_preference_widget:
            self._app_preference_widget.set_preferences()

        k_file = KikoFile(f_name)
        k_file.parse()
        start, end = self._image_frame_range.get_range()
        k_file.set_images(images)

        k_file.save()

        QtWidgets.QMessageBox.information(self, "Success!", "KIKO file exported "
                                          "successfully!")
Beispiel #5
0
class PreviewWidget(QtWidgets.QWidget):
    def __init__(self, kiko_file=None, play_by_default=KIKO_PREVIEW_PLAY,
                 parent=None):
        super(PreviewWidget, self).__init__(parent=parent)

        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                           QtWidgets.QSizePolicy.Expanding)

        self._play_by_default = play_by_default
        self._current_image = QtGui.QImage()

        self._scrubbing_line_position = 5
        self._mouse_over = False

        self.file = kiko_file

    @property
    def file(self):
        return self._kiko_file

    @file.setter
    def file(self, kiko_file):
        if isinstance(kiko_file, KikoFile):
            self._static_image_only = kiko_file.num_images == 0
            self._kiko_file = kiko_file
        else:
            self._static_image_only = (kiko_file is None or
                                   not kiko_file.endswith(KIKO_FILE_EXTENSION))

            if not self._static_image_only:
                self._kiko_file = KikoFile(kiko_file)
                self._kiko_file.parse()

        self._static_image = QtGui.QImage()
        if self._static_image_only:
            self._static_image.load(get_image('kiko.jpg'))
        else:
            self._scrubbing_line_position = 5

            if self._kiko_file.num_images > 0:
                self._static_image.loadFromData(self._kiko_file.get_image(0))

                self._timer = QtCore.QTimer(self)
                self._timer.setInterval(1000 / KIKO_PREVIEW_FPS)
                self._timer.timeout.connect(self._next_frame)
            else:
                self._static_image.load(get_image('kiko.jpg'))
                self._static_image_only = True

        self.setMouseTracking(not self._static_image_only)

        self._current_image = self._static_image
        self.setMaximumWidth(self._static_image.width())
        self.setMaximumHeight(self._static_image.height())

        if not self._current_image.isNull():
            self.setMinimumHeight(self.width() / self.aspect_ratio)

        if self._play_by_default:
            self.play()
        else:
            self.repaint()

    def resizeEvent(self, event):
        if not self._current_image.isNull():
            self.setMinimumHeight(self.width() / self.aspect_ratio)

        if self._scrubbing_line_position:
            self._scrubbing_line_position *= (float(event.size().width()) /
                                             float(event.oldSize().width()))

        super(PreviewWidget, self).resizeEvent(event)

    def play(self):
        if not self._static_image_only and not self._timer.isActive():
            self._timer.start()

    def pause(self):
        if not self._static_image_only and self._timer.isActive():
            self._timer.stop()

    def _next_frame(self):
        self._frame_number += 1
        if self._frame_number > self._kiko_file.num_images - 1:
            self._frame_number = 0
        self._current_image.loadFromData(self._kiko_file.get_image(
                                                            self._frame_number))
        self.repaint()

    @property
    def aspect_ratio(self):
        if self._current_image.isNull():
            return None

        w = float(self._current_image.width())
        h = float(self._current_image.height())
        return w / h

    def mouseMoveEvent(self, event):
        if not self._static_image_only and not self._play_by_default:
            w = self.width()

            ratio = float(event.pos().x()) / float(w)
            ratio = max(0, min(ratio, 1))

            frame_number = int(round((self._kiko_file.num_images - 1) * ratio))

            self._current_image.loadFromData(self._kiko_file.get_image(
                                                                frame_number))


            self._scrubbing_line_position = max(5, min(event.pos().x(), w - 5))
            self.repaint()

        super(PreviewWidget, self).mouseMoveEvent(event)

    def enterEvent(self, event):
        self._mouse_over = True
        super(PreviewWidget, self).enterEvent(event)

    def leaveEvent(self, event):
        self._mouse_over = False
        self.repaint()

        super(PreviewWidget, self).leaveEvent(event)

    def hideEvent(self, event):
        if self._play_by_default:
            self.pause()
        super(PreviewWidget, self).hideEvent(event)

    def showEvent(self, event):
        if self._play_by_default:
            self.play()
        super(PreviewWidget, self).showEvent(event)

    def paintEvent(self, event):
        if not self._current_image.isNull():
            painter = QtGui.QPainter(self)
            painter.setRenderHint(QtGui.QPainter.Antialiasing)

            w = min(self._current_image.width(), self.width())
            h = w / self.aspect_ratio

            #image
            pen = QtGui.QPen()
            pen.setColor(QtGui.QColor(0, 0, 0, 0))
            pen.setJoinStyle(QtCore.Qt.RoundJoin)
            brush = QtGui.QBrush(self._current_image.scaledToWidth(w,
                                                QtCore.Qt.SmoothTransformation))
            painter.setBrush(brush)
            painter.setPen(pen)
            painter.drawRoundedRect(0, 0, w, h, 10, 10)

            #border
            path = QtGui.QPainterPath()
            path.addRoundedRect(QtCore.QRectF(0, 0, w, h), 10, 10)
            pen = QtGui.QPen(QtCore.Qt.black, 3)
            painter.setPen(pen)
            painter.drawPath(path)

            if not self._play_by_default and self._scrubbing_line_position:
                x = self._scrubbing_line_position

                sh = h - 8
                sy = 4
                if not self._mouse_over:
                    sh = 4
                    sy = h - 8

                path = QtGui.QPainterPath()
                path.addRoundedRect(QtCore.QRectF(x - 2, sy, 4, sh), 5, 5)
                pen = QtGui.QPen(QtGui.QColor(255, 255, 255, 123), 3)
                painter.setPen(pen)
                painter.drawPath(path)

        super(PreviewWidget, self).paintEvent(event)
Beispiel #6
0
    def export_to_file(self, file_name, objects=None, operators=None,
                       hierarchy=False, keep_previous_images=False,
                       start_frame=None, end_frame=None,
                       force_op_evaluation=False, channel_filter=None):
        """
        :param file_name: the kiko file path, the file extension determines if
                          a preview is going to be exported (kiko) or not (kb).
        :param objects: The list of objects to processs
        :param operators: list of operators to use for this export
        :param hierarchy: enables the hierarchy mode
        :param keep_previous_images: keeps the images contained by the kiko file
                                     if it already exists
        :param start_frame: the animation start frame
        :param end_frame: the animation end frame
        :param force_op_evaluation: force all operators evaluation
        :param channel_filter: filter the list of channels to export
        """

        if self._facade is None:
            raise InvalidFacadeException('Cannot export file without a facade. '
                                'Please create a new kikoManager with a facade')

        ops = []
        operators = operators or OperatorsFactory().get_all_operator_names(
                                                    self._facade.get_app_name())
        for o in operators:
            op_c = None
            if isinstance(o, tuple):
                if OperatorsFactory.has_operator(o[0], version=o[1]):
                    op_c = OperatorsFactory().get_operator(o[0], o[1])
            else:
                op_ver = OperatorsFactory().get_latest_version(o)
                if not op_ver is None:
                    op_c = OperatorsFactory().get_operator(o, op_ver)

            if op_c is None:
                raise KikoManagerException('Could not find operator %s' % o)

            if not op_c.is_app_supported(self._facade.get_app_name()):
                continue

            ops.append(op_c)

        if not ops:
            raise KikoManagerException("No valid operator found.")

        if objects:
            objs = [self._facade.get_node_by_name(o) for o in objects]
        else:
            objs = self._facade.get_selection()

        if not objs:
            raise KikoManagerException("No obj was selected or passed as arg.")

        k_file = KikoFile(file_name)
        if keep_previous_images:
            k_file.parse()
        s = serializer.Serializer(facade=self._facade)
        k_file.data = s.serialize(file_name, objs, hierarchy=hierarchy,
                                  operators=ops, start_frame=start_frame,
                                  end_frame=end_frame,
                                  force_op_evaluation=force_op_evaluation,
                                  channel_filter=channel_filter)
        k_file.save()
Beispiel #7
0
    def import_from_file(self, file_name, objects=None, item_op_priority=None,
                         channel_op_priority=None, import_obj_method=None,
                         import_anim_method=None, str_replacements=None,
                         obj_mapping=None, prefix_to_add=None,
                         suffix_to_add=None, scale_using_fps=False,
                         frame_value=0, ignore_item_chunks=False,
                         start_frame=None, end_frame=None):
        """
        :param file_name: the kiko file path
        :param objects: The list of objects to processs
        :param item_op_priority: the priority list for item operators
        :param channel_op_priority: the priority list for channel operators
        :param import_obj_method: import object method
        :param import_anim_method: the import animation method
        :param str_replacements: a dictionary of string replacements for item
                                 mapping
        :param obj_mapping: object/channel mapping
        :param prefix_to_add: a prefix to add to the item names for item
                              matching
        :param suffix_to_add: a suffix to add to the item names for item
                              matching
        :param scale_using_fps: scales the animation by using the ratio between
                                the frame rate used when exporting the kiko file
                                and the current scene frame rate
        :param frame_value: a frame offset value
        :param ignore_item_chunks: if True ignores item chunks/operators
        :param start_frame: data stored in the kiko file for key frames before
                            this value will be ignored
        :param end_frame: data stored in the kiko file for key frames after
                          this value will be ignored
        """

        if self._facade is None:
            raise InvalidFacadeException('Cannot import file without a facade. '
                                'Please create a new kikoManager with a facade')

        k_file = KikoFile(file_name)
        k_file.parse()

        if import_obj_method is None:
            import_obj_method = IMPORT_METHODS.OBJECT.NAME
        elif not import_obj_method in IMPORT_METHODS.OBJECT.all():
            raise KikoManagerException('Invalid object import method given')
        flatten_hierarchy = import_obj_method != IMPORT_METHODS.OBJECT.HIERARCHY

        if import_anim_method is None:
            import_anim_method = IMPORT_METHODS.ANIMATION.APPLY
        elif not import_anim_method in IMPORT_METHODS.ANIMATION.all():
            raise KikoManagerException('Invalid animation import method given')

        if item_op_priority or channel_op_priority:
            all_op = (item_op_priority or []) + (channel_op_priority or [])
            for o in all_op:
                op_ver = OperatorsFactory().get_latest_version(o)
                if op_ver is None:
                    raise KikoManagerException("Operators %s not found" % o)

                op_c = OperatorsFactory().get_operator(o, op_ver)
                if not op_c.is_app_supported(self._facade.get_app_name()):
                    raise KikoManagerException("Operator %s does not support %s"
                                            % (o, self._facade.get_app_name()))

        if obj_mapping:
            #building a new map in case there is some channel remapping
            temp_mapping = {}
            for key, value in obj_mapping.iteritems():
                tokens = key.split('.')
                if (len(tokens) == 2) != ('.' in value):
                    raise KikoManagerException("Cannot map channel to object "
                                               "or viceversa: %s -> %s" %
                                               (key, value))

                if len(tokens) == 2:
                    if (not tokens[0] in temp_mapping or
                            not isinstance(temp_mapping[tokens[0]], list)):
                        temp_mapping[tokens[0]] = []

                    vts = value.split('.')
                    temp_mapping[tokens[0]].append((tokens[1], vts[0], vts[1]))
                else:
                    temp_mapping[key] = value
            obj_mapping = temp_mapping

        if objects:
            objs = [self._facade.get_node_by_name(o) for o in objects]
        else:
            objs = self._facade.get_selection()

        if not objs:
            msg = "No obj was selected or passed as arg."
            if import_obj_method == IMPORT_METHODS.OBJECT.NAME:
                warnings.warn(msg + " Trying to match items by name.")
            else:
                raise KikoManagerException(msg)

        d = deserializers.DeserializerManager.get_deserializer(k_file.version,
                                                               self._facade)
        root = d.get_root_from_data(k_file.data,
                                    flatten_hierarchy=flatten_hierarchy,
                                    ignore_item_chunks=ignore_item_chunks)

        t_mult = ((float(self._facade.get_fps()) / root.fps)
                  if scale_using_fps else 1)

        self._facade.pre_import()

        d.load_data(root, objs, item_op_priority=item_op_priority,
                    channel_op_priority=channel_op_priority,
                    import_obj_method=import_obj_method,
                    import_anim_method=import_anim_method,
                    str_replacements=str_replacements, obj_mapping=obj_mapping,
                    prefix_to_add=prefix_to_add, suffix_to_add=suffix_to_add,
                    frame_value=frame_value, time_multiplier=t_mult,
                    start_frame=start_frame, end_frame=end_frame)

        self._facade.post_import()