Verified Commit 70b167f4 authored by Kuntal  Majumder's avatar Kuntal Majumder 😟

Optimized the algorithm, implemented checkpoints

Ref T10894
parent 79aeb782
......@@ -142,54 +142,17 @@ private:
KisMagneticWorker::KisMagneticWorker(KisPaintDeviceSP dev) :
m_dev(dev)
{
KisGaussianKernel::applyLoG(m_dev, m_dev->exactBounds(), 2, 1.0, QBitArray(), 0);
KisLazyFillTools::normalizeAndInvertAlpha8Device(m_dev, m_dev->exactBounds());
}
QRect KisMagneticWorker::calculateRect(QPoint p1, QPoint p2, int radius) const {
// I am sure there is a simpler version of it which exists but well
// Calculates a bounding rectangle based on the radius,
// --------------------------------
// | ------------------- |
// | | A* | |
// | | | |
// | | *B| |
// | ------------------- |
// --------------------------------
double slope = (p2.y() - p1.y())/(p2.x() - p1.x());
QPoint a,b,c,d;
if(slope != 0){
slope = -1/slope;
double denom = 2 * std::sqrt(slope*slope+1);
double numer = radius/denom;
double fac1 = numer/denom;
denom = 2 * denom;
numer = 3 * slope * numer;
double fac2 = numer/denom;
a = QPoint(p1.x() - fac1, p1.y() - fac2);
b = QPoint(p1.x() + fac1, p1.y() + fac2);
c = QPoint(p2.x() - fac1, p2.y() - fac2);
d = QPoint(p2.x() + fac1, p2.y() + fac2);
}else{
double fac = radius/2;
a = QPoint(p1.x() - fac, p1.y() - fac);
b = QPoint(p1.x() + fac, p1.y() + fac);
c = QPoint(p2.x() - fac, p2.y() - fac);
d = QPoint(p2.x() + fac, p2.y() + fac);
}
QPolygon p(QVector<QPoint>{a,b,c,d});
return p.boundingRect();
}
{ }
QVector<QPointF> KisMagneticWorker::computeEdge(int radius, QPoint begin, QPoint end) {
//QRect rect = calculateRect(begin, end, radius);
QRect rect = QPolygon(QVector<QPoint>{begin, end}).boundingRect();
rect.setSize(rect.size()*radius);
QRect rect(QPoint(0,0), QSize(radius*2, radius*2));
rect.moveCenter(begin);
KisGaussianKernel::applyLoG(m_dev, rect, 2, 1.0, QBitArray(), 0);
KisLazyFillTools::normalizeAndInvertAlpha8Device(m_dev, rect);
VertexDescriptor goal(end);
VertexDescriptor start(begin);
KisMagneticGraph g(m_dev, rect);
......@@ -222,11 +185,11 @@ QVector<QPointF> KisMagneticWorker::computeEdge(int radius, QPoint begin, QPoint
}catch(GoalFound const&){
for(VertexDescriptor u=goal; u!=start; u = pmap[u]){
result.push_back(QPointF(u.x,u.y));
result.push_front(QPointF(u.x,u.y));
}
}
result.push_back(QPoint(start.x,start.y));
result.push_front(QPoint(start.x,start.y));
return result;
}
......@@ -30,8 +30,6 @@ public:
KisMagneticWorker(KisPaintDeviceSP dev);
QVector<QPointF> computeEdge(int radius, QPoint start, QPoint end);
private:
QRect calculateRect(QPoint p1, QPoint p2, int radius) const;
KisPaintDeviceSP m_dev;
};
......
......@@ -55,7 +55,7 @@ KisToolSelectMagnetic::KisToolSelectMagnetic(KoCanvasBase *canvas)
: KisToolSelect(canvas,
KisCursor::load("tool_magnetic_selection_cursor.svg", 16, 16),
i18n("Magnetic Selection")),
m_continuedMode(false), m_complete(true), m_frequency(20)
m_continuedMode(false), m_complete(true), m_checkPoint(0), m_radius(20)
{ }
KisToolSelectMagnetic::~KisToolSelectMagnetic()
......@@ -96,10 +96,21 @@ void KisToolSelectMagnetic::mouseMoveEvent(KoPointerEvent *event)
m_lastCursorPos = convertToPixelCoord(event);
auto current = QPoint(m_lastCursorPos.x(), m_lastCursorPos.y());
m_points = m_worker.computeEdge(15, m_lastAnchor, current);
auto point_set = m_worker.computeEdge(m_radius, m_lastAnchor, current);
int num = m_points.count();
m_points.resize(m_radius * (num/m_radius));
m_points.append(point_set);
num = m_points.count();
if(num/20 >= 1) {
m_checkPoint = m_radius * (num/m_radius) - 1;
m_lastAnchor = QPoint(m_points[m_checkPoint].x(), m_points[m_checkPoint].y());
qDebug() << m_lastAnchor;
}
m_paintPath = QPainterPath();
m_paintPath.moveTo(pixelToView(m_points[m_points.count()-1]));
for(int i=m_points.count()-2; i>0;i--){
m_paintPath.moveTo(pixelToView(m_points[0]));
for(int i=1; i<m_points.count();i++){
m_paintPath.lineTo(pixelToView(m_points[i]));
}
......
......@@ -60,13 +60,14 @@ private:
void updateCanvas();
QPainterPath m_paintPath;
vQPointF m_points;
QVector<QPointF> m_points;
bool m_continuedMode;
QPointF m_lastCursorPos;
QPoint m_lastAnchor;
bool m_complete;
KisMagneticWorker m_worker;
int m_frequency;
uint m_checkPoint;
uint m_radius;
};
class KisToolSelectMagneticFactory : public KisSelectionToolFactoryBase
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment