From 2ca22f1bf89dae76745e7b046843190108a74424 Mon Sep 17 00:00:00 2001 From: Till Theato Date: Sat, 19 Mar 2011 23:12:57 +0000 Subject: [PATCH] start documenting the rotoscoping code svn path=/trunk/kdenlive/; revision=5506 --- effects/README | 2 +- src/rotoscoping/rotowidget.cpp | 20 +++++++++++++++++++- src/rotoscoping/rotowidget.h | 10 ++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/effects/README b/effects/README index b36ba564..fc720603 100644 --- a/effects/README +++ b/effects/README @@ -29,7 +29,7 @@ The basic structure of a XML filter description: -------------------------------------------------------------------------------------- Line 1: - - required to make strings in the effect translatable + - required to make strings used in the effect translatable Line 2: - tag: MLT ("mlt_service") name of the effect - id: internal kdenlive id, can be anything, but must be unique for each effect diff --git a/src/rotoscoping/rotowidget.cpp b/src/rotoscoping/rotowidget.cpp index 93711695..abfef3dd 100644 --- a/src/rotoscoping/rotowidget.cpp +++ b/src/rotoscoping/rotowidget.cpp @@ -58,6 +58,9 @@ RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode if (m_data.canConvert(QVariant::Map)) { + /* + * pass keyframe data to keyframe timeline + */ QList keyframes; QMap map = m_data.toMap(); QMap ::const_iterator i = map.constBegin(); @@ -76,6 +79,7 @@ RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode } m_data = QVariant(map); } else { + // static (only one keyframe) m_keyframeWidget->setKeyframes(QList () << 0); } @@ -137,6 +141,9 @@ void RotoWidget::slotUpdateData(int pos, bool editing) int width = m_monitor->render->frameRenderWidth(); int height = m_monitor->render->renderHeight(); + /* + * use the position of the on-monitor points to create a storable list + */ QList spline = m_item->getPoints(); QList vlist; foreach (const BPoint &point, spline) { @@ -148,6 +155,8 @@ void RotoWidget::slotUpdateData(int pos, bool editing) if (m_data.canConvert(QVariant::Map)) { QMap map = m_data.toMap(); + // replace or insert at position + // we have to fill with 0s to maintain the correct order map[QString::number((pos < 0 ? m_keyframeWidget->getPosition() : pos) + m_in).rightJustified(qRound(log10((double)m_out)), '0')] = QVariant(vlist); m_data = QVariant(map); } else { @@ -170,6 +179,7 @@ QString RotoWidget::getSpline() void RotoWidget::slotPositionChanged(int pos, bool seek) { + // do not update while the spline is being edited (points are being dragged) if (m_item->editing()) return; @@ -184,16 +194,22 @@ void RotoWidget::slotPositionChanged(int pos, bool seek) QMap ::const_iterator i = map.constBegin(); int keyframe1, keyframe2; keyframe1 = keyframe2 = i.key().toInt(); + // find keyframes next to pos while (i.key().toInt() < pos && ++i != map.constEnd()) { keyframe1 = keyframe2; keyframe2 = i.key().toInt(); } if (keyframe1 != keyframe2 && pos < keyframe2) { + /* + * in between two keyframes + * -> interpolate + */ QList p1 = getPoints(keyframe1); QList p2 = getPoints(keyframe2); qreal relPos = (pos - keyframe1) / (qreal)(keyframe2 - keyframe1 + 1); + // additionaly points are ignored (same behavior as MLT filter) int count = qMin(p1.count(), p2.count()); for (int i = 0; i < count; ++i) { BPoint bp; @@ -280,8 +296,10 @@ void RotoWidget::slotRemoveKeyframe(int pos) map.remove(QString::number(pos + m_in).rightJustified(qRound(log10((double)m_out)), '0')); m_data = QVariant(map); - if (m_data.toMap().count() == 1) + if (m_data.toMap().count() == 1) { + // only one keyframe -> switch from map to list again m_data = m_data.toMap().begin().value(); + } slotPositionChanged(m_keyframeWidget->getPosition(), false); emit valueChanged(); diff --git a/src/rotoscoping/rotowidget.h b/src/rotoscoping/rotowidget.h index dc385f67..93dddbec 100644 --- a/src/rotoscoping/rotowidget.h +++ b/src/rotoscoping/rotowidget.h @@ -37,7 +37,10 @@ public: RotoWidget(QString data, Monitor *monitor, int in, int out, Timecode t, QWidget* parent = 0); virtual ~RotoWidget(); + /** @brief Returns the spline(s) in the JSON format used by filter_rotoscoping (MLT). */ QString getSpline(); + + /** @brief Passed on to the keyframe timeline. Switches between frames and hh:mm:ss:ff timecode. */ void updateTimecodeFormat(); public slots: @@ -62,6 +65,10 @@ private: int m_in; int m_out; + /** @brief Returns the list of cubic Bézier points that form the spline at position @param keyframe. + * The points are brought from the range [0, 1] into project resolution space. + * This function does not do any interpolation and therfore will only return a list when a keyframe at the given postion exists. + * Set @param keyframe to -1 if only one keyframe currently exists. */ QList getPoints(int keyframe); private slots: @@ -69,9 +76,12 @@ private slots: * @param renderPos Postion of the Monitor / Timeline cursor */ void slotCheckMonitorPosition(int renderPos); + /** @brief Updates/Creates the spline at @param pos based on the on-monitor items. */ void slotUpdateData(int pos = -1, bool editing = false); + /** @brief Updates/Creates the spline at the current timeline position based on the on-monitor items. */ void slotUpdateData(bool editing); + /** @brief Updates the on-monitor items to fit the spline at position @param pos. */ void slotPositionChanged(int pos, bool seek = true); void slotAddKeyframe(int pos = -1); -- 2.39.2