lines
oldfilm
tcolor
+rotoscoping
#effects that have simplekeyframes
vignette
swapchannels.xml
audiobalance.xml
audiopan.xml
+rotoscoping.xml
DESTINATION ${DATA_INSTALL_DIR}/kdenlive/effects)
--- /dev/null
+<!DOCTYPE kpartgui>
+<effect tag="rotoscoping" id="rotoscoping">
+ <name>Rotoscoping</name>
+ <description>Keyframable vector based rotoscoping</description>
+ <author>Till Theato</author>
+
+ <parameter type="list" name="mode" default="alpha" paramlist="alpha,matte,rgb">
+ <paramlistdisplay>Alpha,Matte,RGB</paramlistdisplay>
+ <name>Mode</name>
+ </parameter>
+
+ <parameter type="list" name="alpha_operation" default="clear" paramlist="clear,max,min,add,sub">
+ <paramlistdisplay>Write on clear,Maximum,Minimum,Add,Subtract</paramlistdisplay>
+ <name>Alpha Operation</name>
+ </parameter>
+
+ <parameter type="bool" name="invert" default="0">
+ <name>Invert</name>
+ </parameter>
+
+ <parameter type="constant" name="precision" max="500" min="1" default="1">
+ <name>Precision</name>
+ </parameter>
+
+ <parameter type="roto-spline" name="spline" default="[[[0,1],[0,0],[1,0]],[[1,0],[1,1],[0,1]]]"> <!-- TODO: set default to "" -->
+ <name>Rotoscopy Spline</name>
+ </parameter>
+</effect>
add_subdirectory(kiss_fft)
add_subdirectory(mimetypes)
add_subdirectory(onmonitoritems)
+add_subdirectory(rotoscoping)
add_subdirectory(widgets)
macro_optional_find_package(Nepomuk)
include(FindQImageBlitz)
+find_package(QJSON)
+
include_directories(
${KDE4_INCLUDE_DIR}
${KDE4_INCLUDE_DIR}/KDE
${QT_INCLUDES}
${LIBMLT_INCLUDE_DIR}
${LIBMLTPLUS_INCLUDE_DIR}
+ ${QJSON_INCLUDE_DIR}
${QDBUS_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src/colorcorrection
${CMAKE_SOURCE_DIR}/src/kiss_fft
${CMAKE_SOURCE_DIR}/src/onmonitoritems
+ ${CMAKE_SOURCE_DIR}/src/onmonitoritems/rotoscoping
${CMAKE_SOURCE_DIR}/src/widgets
)
blackmagic/devices.cpp
onmonitoritems/onmonitorrectitem.cpp
onmonitoritems/onmonitorcornersitem.cpp
+ onmonitoritems/rotoscoping/splineitem.cpp
+ onmonitoritems/rotoscoping/bpointitem.cpp
cornerswidget.cpp
kiss_fft/_kiss_fft_guts.h
kiss_fft/kiss_fft.c
beziercurve/cubicbezierspline.cpp
dragvalue.cpp
monitoreditwidget.cpp
+ rotoscoping/rotowidget.cpp
)
add_definitions(${KDE4_DEFINITIONS})
${KDE4_KROSSUI_LIBS}
${CMAKE_DL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
+ ${QJSON_LIBRARIES}
)
if(Q_WS_X11)
#include "doubleparameterwidget.h"
#include "cornerswidget.h"
#include "beziercurve/beziersplinewidget.h"
+#include "rotoscoping/rotowidget.h"
#include <KDebug>
#include <KLocale>
QString depends = pa.attribute("depends");
if (!depends.isEmpty())
meetDependency(paramName, type, EffectsList::parameter(e, depends));
+ } else if (type == "roto-spline") {
+ RotoWidget *roto = new RotoWidget(value, m_monitor, m_in, m_out, this);
+ roto->slotShowScene(!disable);
+ connect(roto, SIGNAL(valueChanged()), this, SLOT(collectAllParameters()));
+ connect(roto, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int)));
+ connect(this, SIGNAL(syncEffectsPos(int)), roto, SLOT(slotSyncPosition(int)));
+ connect(this, SIGNAL(effectStateChanged(bool)), roto, SLOT(slotShowScene(bool)));
+ m_vbox->addWidget(roto);
+ m_valueItems[paramName] = roto;
} else if (type == "wipe") {
Wipeval *wpval = new Wipeval;
wpval->setupUi(toFillin);
QString depends = pa.attributes().namedItem("depends").nodeValue();
if (!depends.isEmpty())
meetDependency(paramName, type, EffectsList::parameter(newparam, depends));
+ } else if (type == "roto-spline") {
+ RotoWidget *widget = static_cast<RotoWidget *>(m_valueItems.value(paramName));
+ setValue = widget->getSpline();
} else if (type == "wipe") {
Wipeval *wp = (Wipeval*)m_valueItems.value(paramName);
wipeInfo info;
-# Empty cmake file to satisfy CMake
\ No newline at end of file
+add_subdirectory(rotoscoping)
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "bpointitem.h"
+#include "splineitem.h"
+
+#include <QPainter>
+#include <QGraphicsSceneMouseEvent>
+#include <QCursor>
+
+
+BPointItem::BPointItem(BPoint point, QGraphicsItem* parent) :
+ QAbstractGraphicsShapeItem(parent),
+ m_selection(-1)
+{
+ setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
+
+ QPen framepen(Qt::SolidLine);
+ framepen.setColor(Qt::yellow);
+ setPen(framepen);
+ setBrush(Qt::NoBrush);
+ setAcceptHoverEvents(true);
+
+ setPos(point.p);
+ m_point.h1 = mapFromScene(point.h1);
+ m_point.p = mapFromScene(point.p);
+ m_point.h2 = mapFromScene(point.h2);
+ m_point.handlesLinked = false;
+}
+
+BPoint BPointItem::getPoint()
+{
+ return BPoint(mapToScene(m_point.h1), mapToScene(m_point.p), mapToScene(m_point.h2));
+}
+
+int BPointItem::type() const
+{
+ return Type;
+}
+
+QRectF BPointItem::boundingRect() const
+{
+ QPolygonF p = QPolygonF() << m_point.h1 << m_point.p << m_point.h2;
+ return p.boundingRect().adjusted(-6, -6, 6, 6);
+}
+
+void BPointItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ painter->setPen(QPen(Qt::yellow, 1, Qt::SolidLine));
+ painter->setBrush(QBrush(isSelected() ? Qt::red : Qt::yellow));
+ painter->setRenderHint(QPainter::Antialiasing);
+
+ double handleSize = 6 / painter->matrix().m11();
+ double handleSizeHalf = handleSize / 2;
+
+ QPolygonF handle = QPolygonF() << QPointF(0, -handleSizeHalf) << QPointF(handleSizeHalf, 0) << QPointF(0, handleSizeHalf) << QPointF(-handleSizeHalf, 0);
+
+ painter->drawLine(m_point.h1, m_point.p);
+ painter->drawLine(m_point.p, m_point.h2);
+
+#if QT_VERSION >= 0x040600
+ painter->drawConvexPolygon(handle.translated(m_point.h1.x(), m_point.h1.y()));
+ painter->drawConvexPolygon(handle.translated(m_point.h2.x(), m_point.h2.y()));
+#else
+ tmp = handle;
+ tmp.translate(m_point.h1.x(), m_point.h1.y());
+ p.drawConvexPolygon(tmp);
+ tmp.translate(m_point.h2.x(), m_point.h2.y());
+ p.drawConvexPolygon(tmp);
+#endif
+
+ painter->drawEllipse(QRectF(m_point.p.x() - handleSizeHalf,
+ m_point.p.y() - handleSizeHalf, handleSize, handleSize));
+}
+
+int BPointItem::getSelection(QPointF pos)
+{
+ QPainterPath mouseArea;
+ mouseArea.addRect(pos.x() - 6, pos.y() - 6, 12, 12);
+
+ if (mouseArea.contains(m_point.p))
+ return 1;
+ else if (mouseArea.contains(m_point.h1))
+ return 0;
+ else if (mouseArea.contains(m_point.h2))
+ return 2;
+
+ return -1;
+}
+
+void BPointItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
+{
+ m_selection = getSelection(event->pos());
+
+ if (m_selection < 0) {
+ event->ignore();
+ setSelected(false);
+ } else {
+ setSelected(true);
+ }
+}
+
+void BPointItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
+{
+ prepareGeometryChange();
+ switch (m_selection) {
+ case 0:
+ m_point.setH1(event->pos());
+ break;
+ case 1:
+ m_point.setP(event->pos());
+ break;
+ case 2:
+ m_point.setH2(event->pos());
+ break;
+ }
+
+ if (parentItem()) {
+ SplineItem *parent = qgraphicsitem_cast<SplineItem*>(parentItem());
+ if (parent)
+ parent->updateSpline();
+ }
+}
+
+void BPointItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+QGraphicsItem::mouseReleaseEvent(event);
+}
+
+void BPointItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
+{
+ if (getSelection(event->pos()) < 0)
+ unsetCursor();
+ else
+ setCursor(QCursor(Qt::PointingHandCursor));
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef BPOINTITEM_H
+#define BPOINTITEM_H
+
+#include "bpoint.h"
+
+#include <QtCore>
+#include <QAbstractGraphicsShapeItem>
+
+class BPointItem : public QAbstractGraphicsShapeItem
+{
+public:
+ BPointItem(BPoint point, QGraphicsItem* parent = 0);
+
+ BPoint getPoint();
+
+ enum { Type = UserType + 11 };
+ virtual int type() const;
+
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+protected:
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+
+private:
+ BPoint m_point;
+ int m_selection;
+
+ /** @brief Gets The action mode for the area @param pos +- 4. */
+ int getSelection(QPointF pos);
+};
+
+#endif
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "splineitem.h"
+#include "bpointitem.h"
+
+#include <QGraphicsScene>
+
+SplineItem::SplineItem(const QList< BPoint >& points, QGraphicsItem* parent, QGraphicsScene *scene) :
+ QGraphicsPathItem(parent, scene)
+{
+ QPen framepen(Qt::SolidLine);
+ framepen.setColor(Qt::yellow);
+ setPen(framepen);
+ setBrush(Qt::NoBrush);
+
+ if (points.isEmpty())
+ return;
+
+ QPainterPath path(points.at(0).p);
+ int j;
+ for (int i = 0; i < points.count(); ++i) {
+ new BPointItem(points.at(i), this);
+ j = (i + 1) % points.count();
+ path.cubicTo(points.at(i).h2, points.at(j).h1, points.at(j).p);
+ }
+ setPath(path);
+}
+
+int SplineItem::type() const
+{
+ return Type;
+}
+
+void SplineItem::updateSpline()
+{
+ QPainterPath path(qgraphicsitem_cast<BPointItem *>(childItems().at(0))->getPoint().p);
+
+ BPoint p1, p2;
+ int j;
+ for (int i = 0; i < childItems().count(); ++i) {
+ j = (i + 1) % childItems().count();
+ p1 = qgraphicsitem_cast<BPointItem *>(childItems().at(i))->getPoint();
+ p2 = qgraphicsitem_cast<BPointItem *>(childItems().at(j))->getPoint();
+ path.cubicTo(p1.h2, p2.h1, p2.p);
+ }
+ setPath(path);
+
+ emit changed();
+}
+
+QList <BPoint> SplineItem::getPoints()
+{
+ QList <BPoint> points;
+ foreach (QGraphicsItem *child, childItems())
+ points << qgraphicsitem_cast<BPointItem *>(child)->getPoint();
+ return points;
+}
+
+#include "splineitem.moc"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef SPLINEITEM_H
+#define SPLINEITEM_H
+
+#include <QtCore>
+#include <QGraphicsPathItem>
+
+class BPoint;
+
+class SplineItem : public QObject, public QGraphicsPathItem
+{
+ Q_OBJECT
+
+public:
+ SplineItem(const QList <BPoint> &points, QGraphicsItem* parent = 0, QGraphicsScene *scene = 0);
+
+ enum { Type = UserType + 10 };
+
+ virtual int type() const;
+
+ void updateSpline();
+ QList <BPoint> getPoints();
+
+signals:
+ void changed();
+};
+
+#endif
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "rotowidget.h"
+#include "monitor.h"
+#include "renderer.h"
+#include "monitorscene.h"
+#include "monitoreditwidget.h"
+#include "onmonitoritems/rotoscoping/bpointitem.h"
+#include "onmonitoritems/rotoscoping/splineitem.h"
+
+#include <qjson/parser.h>
+#include <qjson/serializer.h>
+
+
+RotoWidget::RotoWidget(QString data, Monitor *monitor, int in, int out, QWidget* parent) :
+ QWidget(parent),
+ m_monitor(monitor),
+ m_showScene(true),
+ m_in(in),
+ m_out(out),
+ m_pos(0)
+{
+ MonitorEditWidget *edit = monitor->getEffectEdit();
+ edit->showVisibilityButton(true);
+ m_scene = edit->getScene();
+
+ QJson::Parser parser;
+ bool ok;
+ m_data = parser.parse(data.toUtf8(), &ok);
+ if (!ok) {
+ // :(
+ }
+
+ int width = m_monitor->render->frameRenderWidth();
+ int height = m_monitor->render->renderHeight();
+ QList <BPoint> points;
+ foreach (const QVariant &bpoint, m_data.toList()) {
+ QList <QVariant> l = bpoint.toList();
+ BPoint p;
+ p.h1 = QPointF(l.at(0).toList().at(0).toDouble() * width, l.at(0).toList().at(1).toDouble() * height);
+ p.p = QPointF(l.at(1).toList().at(0).toDouble() * width, l.at(2).toList().at(1).toDouble() * height);
+ p.h2 = QPointF(l.at(2).toList().at(0).toDouble() * width, l.at(2).toList().at(1).toDouble() * height);
+ points << p;
+ }
+
+ m_item = new SplineItem(points, NULL, m_scene);
+
+ connect(m_item, SIGNAL(changed()), this, SLOT(slotUpdateData()));
+ connect(edit, SIGNAL(showEdit(bool)), this, SLOT(slotShowScene(bool)));
+ connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
+}
+
+RotoWidget::~RotoWidget()
+{
+ m_scene->removeItem(m_item);
+ delete m_item;
+
+ if (m_monitor) {
+ MonitorEditWidget *edit = m_monitor->getEffectEdit();
+ edit->showVisibilityButton(false);
+ edit->removeCustomControls();
+ m_monitor->slotEffectScene(false);
+ }
+}
+
+void RotoWidget::slotCheckMonitorPosition(int renderPos)
+{
+ if (m_showScene)
+ emit checkMonitorPosition(renderPos);
+}
+
+void RotoWidget::slotSyncPosition(int relTimelinePos)
+{
+ Q_UNUSED(relTimelinePos);
+}
+
+void RotoWidget::slotShowScene(bool show)
+{
+ m_showScene = show;
+ if (!m_showScene)
+ m_monitor->slotEffectScene(false);
+ else
+ slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
+}
+
+void RotoWidget::slotUpdateData()
+{
+ int width = m_monitor->render->frameRenderWidth();
+ int height = m_monitor->render->renderHeight();
+
+ QList <BPoint> spline = m_item->getPoints();
+ QList <QVariant> vlist;
+ foreach (const BPoint &point, spline) {
+ QList <QVariant> pl;
+ for (int i = 0; i < 3; ++i)
+ pl << QVariant(QList <QVariant>() << QVariant(point[i].x() / width) << QVariant(point[i].y() / height));
+ vlist << QVariant(pl);
+ }
+ m_data = QVariant(vlist);
+
+ emit valueChanged();
+}
+
+QString RotoWidget::getSpline()
+{
+ QJson::Serializer serializer;
+ return QString(serializer.serialize(m_data));
+}
+
+#include "rotowidget.moc"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef ROTOWIDGET_H
+#define ROTOWIDGET_H
+
+#include "bpoint.h"
+
+#include <QWidget>
+
+class Monitor;
+class MonitorScene;
+class SplineItem;
+
+class RotoWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ RotoWidget(QString data, Monitor *monitor, int in, int out, QWidget* parent = 0);
+ virtual ~RotoWidget();
+
+ QString getSpline();
+
+public slots:
+ /** @brief Switches from normal monitor to monitor scene according to @param show. */
+ void slotShowScene(bool show = true);
+ /** @brief Updates the on-monitor item. */
+ void slotSyncPosition(int relTimelinePos);
+
+signals:
+ void valueChanged();
+ void checkMonitorPosition(int);
+
+
+private:
+ Monitor *m_monitor;
+ MonitorScene *m_scene;
+ bool m_showScene;
+ QVariant m_data;
+ SplineItem *m_item;
+ int m_in;
+ int m_out;
+ int m_pos;
+
+private slots:
+ /** @brief Makes sure the monitor effect scene is only visible if the clip this geometry belongs to is visible.
+ * @param renderPos Postion of the Monitor / Timeline cursor */
+ void slotCheckMonitorPosition(int renderPos);
+
+ void slotUpdateData();
+};
+
+#endif