[calligra/calligra/2.9] krita: Adding a Fish Eye Vanishing Point assistant.
Wolthera van Hovell
griffinvalley at gmail.com
Mon Jun 8 16:47:32 UTC 2015
Git commit aa07868288b87687cd6bcdf56ed26a27ba55bda2 by Wolthera van Hovell.
Committed on 08/06/2015 at 16:47.
Pushed by woltherav into branch 'calligra/2.9'.
Adding a Fish Eye Vanishing Point assistant.
This adds the ability to draw perspective that look lens-deformed.
Like the vanishing point assistant, this assistant is per a set of parallel
lines in a 3d space. So to use it effectively, use two, where the second is at
a 90 degree angle of the first, and add a vanishing point to the center of
both. Or combine one with a parallel ruler and a vanishing point, or even
one with two vanishing points. The possibilities are quite large.
This assistant will not just give feedback/snapping between the vanishing
points, but also give feedback to the relative left and right of the assistant.
This is so you can use it in edge-cases like panoramas with relative ease.
Confirmed to work and to save and load, have fun!
CCMAIL:kimageshop at kde.org
M +1 -0 krita/plugins/assistants/RulerAssistant/CMakeLists.txt
A +216 -0 krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.cc [License: LGPL]
A +59 -0 krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.h [License: LGPL]
M +2 -0 krita/plugins/assistants/RulerAssistant/ruler_assistant_tool.cc
M +6 -0 krita/ui/kis_painting_assistant.cc
M +5 -1 krita/ui/kra/kis_kra_saver.cpp
http://commits.kde.org/calligra/aa07868288b87687cd6bcdf56ed26a27ba55bda2
diff --git a/krita/plugins/assistants/RulerAssistant/CMakeLists.txt b/krita/plugins/assistants/RulerAssistant/CMakeLists.txt
index 24a90d5..f90a8bc 100644
--- a/krita/plugins/assistants/RulerAssistant/CMakeLists.txt
+++ b/krita/plugins/assistants/RulerAssistant/CMakeLists.txt
@@ -12,6 +12,7 @@ set(kritarulerassistanttool_PART_SRCS
ConcentricEllipseAssistant.cc
ruler_assistant_tool.cc
kis_ruler_assistant_tool.cc
+ FisheyePointAssistant.cc
)
kde4_add_ui_files(kritarulerassistanttool_PART_SRCS AssistantsToolOptions.ui )
diff --git a/krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.cc b/krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.cc
new file mode 100644
index 0000000..fb91123
--- /dev/null
+++ b/krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.cc
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2008 Cyrille Berger <cberger at cberger.net>
+ * Copyright (c) 2010 Geoffry Song <goffrie at gmail.com>
+ * Copyright (c) 2014 Wolthera van Hövell tot Westerflier <griffinvalley at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "FisheyePointAssistant.h"
+
+#include "kis_debug.h"
+#include <klocale.h>
+
+#include <QPainter>
+#include <QLinearGradient>
+#include <QTransform>
+
+#include "kis_coordinates_converter.h"
+#include "kis_algebra_2d.h"
+
+#include <math.h>
+#include <limits>
+
+FisheyePointAssistant::FisheyePointAssistant()
+ : KisPaintingAssistant("fisheye-point", i18n("Fish Eye Point assistant"))
+{
+}
+
+QPointF FisheyePointAssistant::project(const QPointF& pt, const QPointF& strokeBegin)
+{
+ const static QPointF nullPoint(std::numeric_limits<qreal>::quiet_NaN(), std::numeric_limits<qreal>::quiet_NaN());
+ Q_ASSERT(handles().size() == 3);
+ e.set(*handles()[0], *handles()[1], *handles()[2]);
+
+ qreal
+ dx = pt.x() - strokeBegin.x(),
+ dy = pt.y() - strokeBegin.y();
+ if (dx * dx + dy * dy < 4.0) {
+ // allow some movement before snapping
+ return strokeBegin;
+ }
+
+ //set the extrapolation ellipse.
+ if (e.set(*handles()[0], *handles()[1], *handles()[2])){
+ QLineF radius(*handles()[1], *handles()[0]);
+ radius.setAngle(fmod(radius.angle()+180.0,360.0));
+ QLineF radius2(*handles()[0], *handles()[1]);
+ radius2.setAngle(fmod(radius2.angle()+180.0,360.0));
+ if ( extraE.set(*handles()[0], *handles()[1],strokeBegin ) ) {
+ return extraE.project(pt);
+ } else if (extraE.set(radius.p1(), radius.p2(),strokeBegin)) {
+ return extraE.project(pt);
+ } else if (extraE.set(radius2.p1(), radius2.p2(),strokeBegin)){
+ return extraE.project(pt);
+ }
+ }
+
+ return nullPoint;
+
+}
+
+QPointF FisheyePointAssistant::adjustPosition(const QPointF& pt, const QPointF& strokeBegin)
+{
+ return project(pt, strokeBegin);
+}
+
+void FisheyePointAssistant::drawAssistant(QPainter& gc, const QRectF& updateRect, const KisCoordinatesConverter* converter, bool cached, KisCanvas2* canvas, bool assistantVisible, bool previewVisible)
+{
+ gc.save();
+ gc.resetTransform();
+ QPointF delta(0,0);
+ QPointF mousePos(0,0);
+ QPointF endPoint(0,0);//this is the final point that the line is being extended to, we seek it just outside the view port//
+ QPointF otherHandle(0,0);
+
+ if (canvas){
+ //simplest, cheapest way to get the mouse-position//
+ mousePos= canvas->canvasWidget()->mapFromGlobal(QCursor::pos());
+ }
+ else {
+ //...of course, you need to have access to a canvas-widget for that.//
+ mousePos = QCursor::pos();//this'll give an offset//
+ dbgFile<<"canvas does not exist in ruler, you may have passed arguments incorrectly:"<<canvas;
+ }
+
+ QTransform initialTransform = converter->documentToWidgetTransform();
+
+ if (outline()==true && previewVisible==true){
+ if (handles().size() > 2){
+
+
+ if (e.set(*handles()[0], *handles()[1], *handles()[2])) {
+ if (extraE.set(*handles()[0], *handles()[1], initialTransform.inverted().map(mousePos))){
+ gc.setTransform(initialTransform);
+ gc.setTransform(e.getInverse(), true);
+ QPainterPath path;
+ // Draw the ellipse
+ path.addEllipse(QPointF(0, 0), extraE.semiMajor(), extraE.semiMinor());
+ drawPreview(gc, path);
+ }
+ QLineF radius(*handles()[1], *handles()[0]);
+ radius.setAngle(fmod(radius.angle()+180.0,360.0));
+ if (extraE.set(radius.p1(), radius.p2(), initialTransform.inverted().map(mousePos))){
+ gc.setTransform(initialTransform);
+ gc.setTransform(extraE.getInverse(), true);
+ QPainterPath path;
+ // Draw the ellipse
+ path.addEllipse(QPointF(0, 0), extraE.semiMajor(), extraE.semiMinor());
+ drawPreview(gc, path);
+ }
+ QLineF radius2(*handles()[0], *handles()[1]);
+ radius2.setAngle(fmod(radius2.angle()+180.0,360.0));
+ if (extraE.set(radius2.p1(), radius2.p2(), initialTransform.inverted().map(mousePos))){
+ gc.setTransform(initialTransform);
+ gc.setTransform(extraE.getInverse(), true);
+ QPainterPath path;
+ // Draw the ellipse
+ path.addEllipse(QPointF(0, 0), extraE.semiMajor(), extraE.semiMinor());
+ drawPreview(gc, path);
+ }
+
+ }
+ }
+ }
+ gc.restore();
+
+ KisPaintingAssistant::drawAssistant(gc, updateRect, converter, cached, canvas, assistantVisible, previewVisible);
+
+}
+
+void FisheyePointAssistant::drawCache(QPainter& gc, const KisCoordinatesConverter *converter, bool assistantVisible)
+{
+ if (assistantVisible==false){return;}
+
+ QTransform initialTransform = converter->documentToWidgetTransform();
+
+ if (handles().size() == 2) {
+ // just draw the axis
+ gc.setTransform(initialTransform);
+ QPainterPath path;
+ path.moveTo(*handles()[0]);
+ path.lineTo(*handles()[1]);
+ drawPath(gc, path, snapping());
+ return;
+ }
+ if (e.set(*handles()[0], *handles()[1], *handles()[2])) {
+ // valid ellipse
+
+ gc.setTransform(initialTransform);
+ gc.setTransform(e.getInverse(), true);
+ QPainterPath path;
+ //path.moveTo(QPointF(-e.semiMajor(), -e.semiMinor())); path.lineTo(QPointF(e.semiMajor(), -e.semiMinor()));
+ path.moveTo(QPointF(-e.semiMajor(), -e.semiMinor())); path.lineTo(QPointF(-e.semiMajor(), e.semiMinor()));
+ //path.moveTo(QPointF(-e.semiMajor(), e.semiMinor())); path.lineTo(QPointF(e.semiMajor(), e.semiMinor()));
+ path.moveTo(QPointF(e.semiMajor(), -e.semiMinor())); path.lineTo(QPointF(e.semiMajor(), e.semiMinor()));
+ path.moveTo(QPointF(-(e.semiMajor()*3), -e.semiMinor())); path.lineTo(QPointF(-(e.semiMajor()*3), e.semiMinor()));
+ path.moveTo(QPointF((e.semiMajor()*3), -e.semiMinor())); path.lineTo(QPointF((e.semiMajor()*3), e.semiMinor()));
+ path.moveTo(QPointF(-e.semiMajor(), 0)); path.lineTo(QPointF(e.semiMajor(), 0));
+ //path.moveTo(QPointF(0, -e.semiMinor())); path.lineTo(QPointF(0, e.semiMinor()));
+ // Draw the ellipse
+ path.addEllipse(QPointF(0, 0), e.semiMajor(), e.semiMinor());
+ drawPath(gc, path, snapping());
+ }
+
+}
+
+QRect FisheyePointAssistant::boundingRect() const
+{
+ if (handles().size() != 3) return KisPaintingAssistant::boundingRect();
+ if (e.set(*handles()[0], *handles()[1], *handles()[2])) {
+ return e.boundingRect().adjusted(-(e.semiMajor()*2), -2, (e.semiMajor()*2), 2).toAlignedRect();
+ } else {
+ return QRect();
+ }
+}
+
+QPointF FisheyePointAssistant::buttonPosition() const
+{
+ return (*handles()[0] + *handles()[1]) * 0.5;
+}
+
+
+
+FisheyePointAssistantFactory::FisheyePointAssistantFactory()
+{
+}
+
+FisheyePointAssistantFactory::~FisheyePointAssistantFactory()
+{
+}
+
+QString FisheyePointAssistantFactory::id() const
+{
+ return "fisheye-point";
+}
+
+QString FisheyePointAssistantFactory::name() const
+{
+ return i18n("Fish Eye Point");
+}
+
+KisPaintingAssistant* FisheyePointAssistantFactory::createPaintingAssistant() const
+{
+ return new FisheyePointAssistant;
+}
diff --git a/krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.h b/krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.h
new file mode 100644
index 0000000..8d02a26
--- /dev/null
+++ b/krita/plugins/assistants/RulerAssistant/FisheyePointAssistant.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008 Cyrille Berger <cberger at cberger.net>
+ * Copyright (c) 2010 Geoffry Song <goffrie at gmail.com>
+ * Copyright (c) 2014 Wolthera van Hövell tot Westerflier <griffinvalley at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 2.1 of the License.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _FISHEYEPOINT_ASSISTANT_H_
+#define _FISHEYEPOINT_ASSISTANT_H_
+
+#include "kis_painting_assistant.h"
+#include "Ellipse.h"
+#include <QObject>
+#include <QPolygonF>
+#include <QLineF>
+#include <QTransform>
+//class FisheyePoint;
+
+class FisheyePointAssistant : public KisPaintingAssistant
+{
+public:
+ FisheyePointAssistant();
+ virtual QPointF adjustPosition(const QPointF& point, const QPointF& strokeBegin);
+ //virtual void endStroke();
+ virtual QPointF buttonPosition() const;
+ virtual int numHandles() const { return 3; }
+protected:
+ virtual QRect boundingRect() const;
+ virtual void drawAssistant(QPainter& gc, const QRectF& updateRect, const KisCoordinatesConverter* converter, bool cached = true,KisCanvas2* canvas=0, bool assistantVisible=true, bool previewVisible=true);
+ virtual void drawCache(QPainter& gc, const KisCoordinatesConverter *converter, bool assistantVisible=true);
+private:
+ QPointF project(const QPointF& pt, const QPointF& strokeBegin);
+ mutable Ellipse e;
+ mutable Ellipse extraE;
+};
+
+class FisheyePointAssistantFactory : public KisPaintingAssistantFactory
+{
+public:
+ FisheyePointAssistantFactory();
+ virtual ~FisheyePointAssistantFactory();
+ virtual QString id() const;
+ virtual QString name() const;
+ virtual KisPaintingAssistant* createPaintingAssistant() const;
+};
+
+#endif
diff --git a/krita/plugins/assistants/RulerAssistant/ruler_assistant_tool.cc b/krita/plugins/assistants/RulerAssistant/ruler_assistant_tool.cc
index 7aa1c86..11ebc6c 100644
--- a/krita/plugins/assistants/RulerAssistant/ruler_assistant_tool.cc
+++ b/krita/plugins/assistants/RulerAssistant/ruler_assistant_tool.cc
@@ -28,6 +28,7 @@
#include "InfiniteRulerAssistant.h"
#include "ParallelRulerAssistant.h"
#include "ConcentricEllipseAssistant.h"
+#include "FisheyePointAssistant.h"
//#include "mesh_assistant.h"
K_PLUGIN_FACTORY(RulerAssistantToolFactory, registerPlugin<RulerAssistantToolPlugin>();)
@@ -48,6 +49,7 @@ RulerAssistantToolPlugin::RulerAssistantToolPlugin(QObject *parent, const QVaria
KisPaintingAssistantFactoryRegistry::instance()->add(new InfiniteRulerAssistantFactory);
KisPaintingAssistantFactoryRegistry::instance()->add(new ParallelRulerAssistantFactory);
KisPaintingAssistantFactoryRegistry::instance()->add(new ConcentricEllipseAssistantFactory);
+ KisPaintingAssistantFactoryRegistry::instance()->add(new FisheyePointAssistantFactory);
// KisPaintingAssistantFactoryRegistry::instance()->add(new MeshAssistantFactory);
}
diff --git a/krita/ui/kis_painting_assistant.cc b/krita/ui/kis_painting_assistant.cc
index b5a792e..8f4f2a5 100644
--- a/krita/ui/kis_painting_assistant.cc
+++ b/krita/ui/kis_painting_assistant.cc
@@ -418,6 +418,12 @@ void KisPaintingAssistant::saveXmlList(QDomDocument& doc, QDomElement& assistant
assistantElement.setAttribute("filename", QString("concentric ellipse%1.assistant").arg(count));
assistantsElement.appendChild(assistantElement);
}
+ else if (d->id == "fisheye-point"){
+ QDomElement assistantElement = doc.createElement("assistant");
+ assistantElement.setAttribute("type", "fisheye-point");
+ assistantElement.setAttribute("filename", QString("fisheye-point%1.assistant").arg(count));
+ assistantsElement.appendChild(assistantElement);
+ }
else if (d->id == "ruler"){
QDomElement assistantElement = doc.createElement("assistant");
assistantElement.setAttribute("type", "ruler");
diff --git a/krita/ui/kra/kis_kra_saver.cpp b/krita/ui/kra/kis_kra_saver.cpp
index 48d685a..ecc4bac 100644
--- a/krita/ui/kra/kis_kra_saver.cpp
+++ b/krita/ui/kra/kis_kra_saver.cpp
@@ -251,7 +251,7 @@ bool KisKraSaver::saveAssistants(KoStore* store, QString uri, bool external)
bool KisKraSaver::saveAssistantsList(QDomDocument& doc, QDomElement& element)
{
- int count_ellipse = 0, count_perspective = 0, count_ruler = 0, count_vanishingpoint = 0,count_infiniteruler = 0, count_parallelruler = 0, count_concentricellipse = 0, count_spline = 0;
+ int count_ellipse = 0, count_perspective = 0, count_ruler = 0, count_vanishingpoint = 0,count_infiniteruler = 0, count_parallelruler = 0, count_concentricellipse = 0, count_fisheyepoint = 0, count_spline = 0;
QList<KisPaintingAssistant*> assistants = m_d->doc->assistants();
if (!assistants.isEmpty()) {
QDomElement assistantsElement = doc.createElement("assistants");
@@ -284,6 +284,10 @@ bool KisKraSaver::saveAssistantsList(QDomDocument& doc, QDomElement& element)
assist->saveXmlList(doc, assistantsElement, count_concentricellipse);
count_concentricellipse++;
}
+ else if (assist->id() == "fisheye-point"){
+ assist->saveXmlList(doc, assistantsElement, count_fisheyepoint);
+ count_fisheyepoint++;
+ }
else if (assist->id() == "ruler"){
assist->saveXmlList(doc, assistantsElement, count_ruler);
count_ruler++;
More information about the kimageshop
mailing list