From 564cdb5ec88187bb74e59c086594ff3136f8f4b0 Mon Sep 17 00:00:00 2001 From: ponchio Date: Wed, 22 Jan 2025 18:36:10 +0100 Subject: [PATCH] working on the align functionality --- relightlab/alignframe.cpp | 13 ++++---- relightlab/alignframe.h | 3 +- relightlab/alignpicking.cpp | 30 +++++++++++++---- relightlab/alignpicking.h | 25 ++++++++++++-- relightlab/alignrow.cpp | 54 +++++++++++++++---------------- relightlab/alignrow.h | 8 ++--- relightlab/docs/gettingstarted.md | 18 ++++------- relightlab/docs/home.md | 6 ++-- relightlab/docs/index.md | 2 +- relightlab/helpbutton.cpp | 3 +- relightlab/reflectionview.cpp | 47 +++++++++++++++++++-------- relightlab/reflectionview.h | 42 ++++++++++++++++++------ relightlab/roadmap.md | 3 +- relightlab/sphererow.cpp | 7 ++-- relightlab/sphererow.h | 10 +++--- src/align.cpp | 6 ++++ src/align.h | 3 ++ 17 files changed, 183 insertions(+), 97 deletions(-) diff --git a/relightlab/alignframe.cpp b/relightlab/alignframe.cpp index 5a5f4ff5..ec7f79cc 100644 --- a/relightlab/alignframe.cpp +++ b/relightlab/alignframe.cpp @@ -33,14 +33,15 @@ void AlignFrame::clear() { while(aligns->count() > 0) { QLayoutItem *item = aligns->takeAt(0); AlignRow *row = dynamic_cast(item->widget()); - //row->stopDetecting(); + row->stopFinding(); delete row; } } void AlignFrame::init() { for(Align *align: qRelightApp->project().aligns) { - addAlign(align); + AlignRow *row = addAlign(align); + row->findAlignment(false); } } @@ -49,7 +50,6 @@ void AlignFrame::newAlign() { if(!marker_dialog) marker_dialog = new MarkerDialog(MarkerDialog::ALIGN, this); - //TODO ACTUALLY images might be skipped! Align *align = new Align(qRelightApp->project().images.size()); marker_dialog->setAlign(align); int answer = marker_dialog->exec(); @@ -58,14 +58,15 @@ void AlignFrame::newAlign() { return; } qRelightApp->project().aligns.push_back(align); - addAlign(align); + AlignRow *row = addAlign(align); + row->findAlignment(); + } AlignRow *AlignFrame::addAlign(Align *align) { AlignRow *row = new AlignRow(align); aligns->addWidget(row); - connect(row, SIGNAL(removeme(AlignRow *)), this, SLOT(removeAlign(AlignRow *))); connect(row, SIGNAL(updated()), this, SIGNAL(updated())); return row; @@ -74,7 +75,7 @@ AlignRow *AlignFrame::addAlign(Align *align) { void AlignFrame::removeAlign(AlignRow *row) { layout()->removeWidget(row); -// row->stopDetecting(); + row->stopFinding(); Align *align = row->align; auto &aligns = qRelightApp->project().aligns; diff --git a/relightlab/alignframe.h b/relightlab/alignframe.h index d3c53a15..9a056439 100644 --- a/relightlab/alignframe.h +++ b/relightlab/alignframe.h @@ -21,7 +21,8 @@ Q_OBJECT public slots: void newAlign(); void removeAlign(AlignRow *align); - +signals: + void updated(); private: MarkerDialog *marker_dialog = nullptr; diff --git a/relightlab/alignpicking.cpp b/relightlab/alignpicking.cpp index f0a8c2ed..da4ac038 100644 --- a/relightlab/alignpicking.cpp +++ b/relightlab/alignpicking.cpp @@ -7,24 +7,35 @@ #include #include + +QVariant AlignRect::itemChange(GraphicsItemChange change, const QVariant &value) { + if ((change == ItemPositionChange && scene()) || change == ItemScenePositionHasChanged) { + picker->updateAlignPoint(); + } + return QGraphicsItem::itemChange(change, value); +} + AlignPicking::AlignPicking(QWidget *parent): ImageViewer(parent) { marker_side = 40; - connect(view, SIGNAL(clicked(QPoint)), this, SLOT(click(QPoint))); + rect = new AlignRect(this, 0, 0, 0, 0); + rect->setPen(QPen(Qt::yellow, 2)); + rect->setBrush(Qt::transparent); } void AlignPicking::clear() { - scene().clear(); - rect = nullptr; + if(rect) { + scene().removeItem(rect); + } } void AlignPicking::setAlign(Align *a) { clear(); align = a; - - rect = scene().addRect(a->rect, QPen(Qt::yellow), Qt::red); + rect->setRect(align->rect); + scene().addItem(rect); showImage(0); fit(); @@ -33,7 +44,7 @@ void AlignPicking::setAlign(Align *a) { void AlignPicking::click(QPoint p) { - clear(); + //clear(); QSize imgsize = qRelightApp->project().imgsize; QPointF pos = view->mapToScene(p); @@ -47,5 +58,10 @@ void AlignPicking::click(QPoint p) { pos.setY(std::min(imgsize.height()-marker_side/2.0, pos.y())); align->rect = QRect(pos.x()-marker_side/2.0, pos.y()-marker_side/2.0, marker_side, marker_side); - rect = scene().addRect(align->rect, QPen(Qt::yellow), Qt::red); + rect->setRect(align->rect); +} + +void AlignPicking::updateAlignPoint() { + align->rect = rect->rect().toRect(); } + diff --git a/relightlab/alignpicking.h b/relightlab/alignpicking.h index caa6aa59..b78a9820 100644 --- a/relightlab/alignpicking.h +++ b/relightlab/alignpicking.h @@ -2,11 +2,31 @@ #define ALIGN_PICKING_H #include "imageview.h" +#include class QGraphicsRectItem; class Canvas; class Align; +class AlignPicking; + +class AlignRect: public QGraphicsRectItem { +public: + AlignRect(AlignPicking *_picker, qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = Q_NULLPTR): + QGraphicsRectItem(x, y, w, h, parent), picker(_picker) { + setCursor(Qt::CrossCursor); + setFlag(QGraphicsItem::ItemIsMovable); + setFlag(QGraphicsItem::ItemIsSelectable); + setFlag(QGraphicsItem::ItemSendsScenePositionChanges); + + } + virtual ~AlignRect() {} + +protected: + AlignPicking *picker; + QVariant itemChange(GraphicsItemChange change, const QVariant &value); +}; + class AlignPicking: public ImageViewer { Q_OBJECT @@ -14,8 +34,7 @@ class AlignPicking: public ImageViewer { int marker_side = 40; Align *align = nullptr; - QGraphicsRectItem *rect = nullptr; - + AlignRect *rect = nullptr; AlignPicking(QWidget *parent = nullptr); void setAlign(Align *sphere); @@ -24,7 +43,7 @@ class AlignPicking: public ImageViewer { public slots: void click(QPoint); - + void updateAlignPoint(); }; #endif diff --git a/relightlab/alignrow.cpp b/relightlab/alignrow.cpp index bface326..b19fad51 100644 --- a/relightlab/alignrow.cpp +++ b/relightlab/alignrow.cpp @@ -1,10 +1,11 @@ #include "alignrow.h" + #include "markerdialog.h" #include "relightapp.h" #include "verifydialog.h" #include "reflectionview.h" #include "../src/project.h" -#include "../src/sphere.h" +#include "../src/align.h" #include "processqueue.h" #include @@ -22,7 +23,7 @@ void FindAlignment::run() { mutex.lock(); status = RUNNING; mutex.unlock(); -/* + Project &project = qRelightApp->project(); for(size_t i = 0; i < project.images.size(); i++) { @@ -30,11 +31,11 @@ void FindAlignment::run() { if(image.skip) continue; QImage img(image.filename); - sphere->findHighlight(img, i, update_positions); + align->readThumb(img, i); int progress = std::min(99, (int)(100*(i+1) / project.images.size())); progressed(QString("Detecting highlights"), progress); - } */ + } progressed(QString("Done"), 100); mutex.lock(); status = DONE; @@ -48,19 +49,19 @@ AlignRow::AlignRow(Align *_align, QWidget *parent): QWidget(parent) { columns->setSpacing(20); columns->addWidget(thumb = new QLabel()); -/* position = new PositionView(sphere, rowHeight); + position = new AlignOverview(align->rect, rowHeight); position->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); columns->addWidget(position); - reflections = new ReflectionView(sphere, rowHeight); + /*reflections = new ReflectionView(sphere, rowHeight); reflections->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); columns->addWidget(reflections); */ QVBoxLayout *status_layout = new QVBoxLayout; columns->addLayout(status_layout, 2); status_layout->addStretch(); - status = new QLabel("Locating highlights..."); + status = new QLabel("Loading patches..."); status_layout->addWidget(status); progress = new QProgressBar; progress->setValue(0); @@ -78,15 +79,17 @@ AlignRow::AlignRow(Align *_align, QWidget *parent): QWidget(parent) { connect(remove, SIGNAL(clicked()), this, SLOT(remove())); connect(verify, SIGNAL(clicked()), this, SLOT(verify())); + } void AlignRow::edit() { MarkerDialog *marker_dialog = new MarkerDialog(MarkerDialog::ALIGN, this); marker_dialog->setAlign(align); int answer = marker_dialog->exec(); if(answer == QDialog::Accepted) { - //position->update(); + position->rect = align->rect; + position->update(); //reflections->init(); - //detectHighlights(); + findAlignment(); } } @@ -105,36 +108,31 @@ void AlignRow::remove() { void AlignRow::updateStatus(QString msg, int percent) { status->setText(msg); progress->setValue(percent); - reflections->update(); + //reflections->update(); if(percent == 100) { emit updated(); } } void AlignRow::findAlignment(bool update) { -/* if(sphere->center.isNull()) { - status->setText("Needs at least 3 points."); - return; - } - if(!detect_highlights) { - detect_highlights = new DetectHighlights(sphere, update); - connect(detect_highlights, &DetectHighlights::progress, this, &SphereRow::updateStatus); //, Qt::QueuedConnection); + if(!find_alignment) { + find_alignment = new FindAlignment(align, update); + connect(find_alignment, &FindAlignment::progress, this, &AlignRow::updateStatus); //, Qt::QueuedConnection); } - detect_highlights->stop(); + find_alignment->stop(); ProcessQueue &queue = ProcessQueue::instance(); - queue.removeTask(detect_highlights); - queue.addTask(detect_highlights); - queue.start(); */ + queue.removeTask(find_alignment); + queue.addTask(find_alignment); + queue.start(); } void AlignRow::stopFinding() { - /* - if(detect_highlights) { - if(detect_highlights->isRunning()) { - detect_highlights->stop(); - detect_highlights->wait(); + if(find_alignment) { + if(find_alignment->isRunning()) { + find_alignment->stop(); + find_alignment->wait(); } - detect_highlights->deleteLater(); - } */ + find_alignment->deleteLater(); + } } diff --git a/relightlab/alignrow.h b/relightlab/alignrow.h index 3449cb59..e348aa07 100644 --- a/relightlab/alignrow.h +++ b/relightlab/alignrow.h @@ -10,7 +10,7 @@ class Align; class QLabel; class QProgressBar; -class ReflectionView; +class AlignOverview; class QGraphicsPixmapItem; class FindAlignment: public Task { @@ -26,10 +26,10 @@ class FindAlignment: public Task { class AlignRow: public QWidget { Q_OBJECT public: - Align *align; int rowHeight = 92; - QLabel *thumb; - ReflectionView *reflections; + Align *align = nullptr; + QLabel *thumb = nullptr; + AlignOverview *position = nullptr; QLabel *status = nullptr; QProgressBar *progress = nullptr; FindAlignment *find_alignment = nullptr; diff --git a/relightlab/docs/gettingstarted.md b/relightlab/docs/gettingstarted.md index 2daa208d..57453d32 100644 --- a/relightlab/docs/gettingstarted.md +++ b/relightlab/docs/gettingstarted.md @@ -1,9 +1,9 @@ #Getting started - -1. Prerequisites + + +1. New project 2. Lights 3. Export RTIs 4. Export normals @@ -12,25 +12,21 @@ we do not need to cover every detail. --> ##New project - + ##Light configuration - + ##Export RTI - + #Working with normals - + #Explore the results diff --git a/relightlab/docs/home.md b/relightlab/docs/home.md index f63e8ed6..632b3fbc 100644 --- a/relightlab/docs/home.md +++ b/relightlab/docs/home.md @@ -1,4 +1,6 @@ -# Documentation + +

Getting started

+ A selection of topics, links to to tutorials, etc. @@ -6,7 +8,7 @@ RTI introduction. Publishing on the web. -## Index +

Index

diff --git a/relightlab/docs/index.md b/relightlab/docs/index.md index 2542e7a1..f9553f55 100644 --- a/relightlab/docs/index.md +++ b/relightlab/docs/index.md @@ -1,6 +1,6 @@ # Index -0. Getting started +0. Getting started 1. Interface diff --git a/relightlab/helpbutton.cpp b/relightlab/helpbutton.cpp index d60f128d..037d01b0 100644 --- a/relightlab/helpbutton.cpp +++ b/relightlab/helpbutton.cpp @@ -60,6 +60,7 @@ void HelpedButton::init(QString id) { HelpButton::HelpButton(QString id, QWidget *parent): QToolButton(parent) { setCursor(Qt::PointingHandCursor); setIcon(QIcon::fromTheme("help-circle")); + setId(id); //setStyleSheet("QToolButton { color: #ff00ff; }"); connect(this, SIGNAL(clicked()), this, SLOT(showHelp())); @@ -74,8 +75,6 @@ void HelpButton::showHelp() { QString id = objectName(); HelpDialog &dialog = HelpDialog::instance(); dialog.showPage(id); - //dialog.raise(); - //dialog.exec(); } HelpLabel::HelpLabel(QString txt, QString help_id, QWidget *parent): QWidget(parent) { diff --git a/relightlab/reflectionview.cpp b/relightlab/reflectionview.cpp index 46cd40fc..897315bc 100644 --- a/relightlab/reflectionview.cpp +++ b/relightlab/reflectionview.cpp @@ -7,8 +7,7 @@ #include #include -PositionView::PositionView(Sphere *_sphere, int _height, QWidget *parent): QGraphicsView(parent) { - sphere = _sphere; +MarkerOverview::MarkerOverview(int _height, QWidget *parent): QGraphicsView(parent) { height = _height; setScene(&scene); @@ -19,15 +18,18 @@ PositionView::PositionView(Sphere *_sphere, int _height, QWidget *parent): QGrap img_item = scene.addPixmap(pix); setFixedSize(pix.width()*height/pix.height(), height); - - update(); } -void PositionView::resizeEvent(QResizeEvent */*event*/) { +void MarkerOverview::resizeEvent(QResizeEvent */*event*/) { fitInView(scene.sceneRect()); //img_item); } -void PositionView::update() { +SphereOverview::SphereOverview(QPointF _center, double _radius, int height, QWidget *parent): + MarkerOverview(height, parent), center(_center), radius(_radius) { + update(); +} + +void SphereOverview::update() { // scene.clear(); if(ellipse) scene.removeItem(ellipse); @@ -36,13 +38,30 @@ void PositionView::update() { double scale = size.width()/(double)qRelightApp->project().imgsize.width(); - double radius = sphere->radius*scale; - QPointF scaled_center = sphere->center*scale; - ellipse = scene.addEllipse(QRectF(scaled_center - QPointF(radius, radius), QSize(2*radius, 2*radius)), Qt::NoPen, Qt::green); + double r = radius*scale; + QPointF scaled_center = center*scale; + ellipse = scene.addEllipse(QRectF(scaled_center - QPointF(r, r), QSize(2*r, 2*r)), Qt::NoPen, Qt::green); +} + +AlignOverview::AlignOverview(QRectF _rect, int height, QWidget *parent): + MarkerOverview(height, parent), rect(_rect) { + update(); +} + +void AlignOverview::update() { + + QSizeF size = img_item->boundingRect().size(); + + double scale = size.width()/(double)qRelightApp->project().imgsize.width(); + QRectF r = QRectF(rect.x()*scale, rect.y()*scale, rect.width()*scale, rect.height()*scale); + if(item) + scene.removeItem(item); + + item = scene.addRect(r, Qt::NoPen, Qt::green); } -ReflectionView::ReflectionView(Sphere *_sphere, int _height, QWidget *parent ): QGraphicsView(parent) { +ReflectionOverview::ReflectionOverview(Sphere *_sphere, int _height, QWidget *parent ): QGraphicsView(parent) { sphere = _sphere; height = _height; setScene(&scene); @@ -56,7 +75,7 @@ ReflectionView::ReflectionView(Sphere *_sphere, int _height, QWidget *parent ): update(); } -ReflectionView::~ReflectionView() { +ReflectionOverview::~ReflectionOverview() { for(auto l: lights) { scene.removeItem(l); delete l; @@ -64,7 +83,7 @@ ReflectionView::~ReflectionView() { lights.clear(); } -void ReflectionView::init() { +void ReflectionOverview::init() { scene.clear(); lights.clear(); @@ -84,7 +103,7 @@ void ReflectionView::init() { area->setRotation(sphere->eAngle); } -void ReflectionView::update() { +void ReflectionOverview::update() { for(auto l: lights) { scene.removeItem(l); delete l; @@ -107,7 +126,7 @@ void ReflectionView::update() { } } -void ReflectionView::resizeEvent(QResizeEvent */*event*/) { +void ReflectionOverview::resizeEvent(QResizeEvent */*event*/) { fitInView(img_item->boundingRect()); } diff --git a/relightlab/reflectionview.h b/relightlab/reflectionview.h index f252010f..0d97533b 100644 --- a/relightlab/reflectionview.h +++ b/relightlab/reflectionview.h @@ -8,33 +8,57 @@ class Sphere; class QGraphicsEllipseItem; +class QGraphicsRectItem; -class PositionView: public QGraphicsView { +class MarkerOverview: public QGraphicsView { Q_OBJECT public: - PositionView(Sphere *sphere, int height, QWidget *parent = nullptr); - void update(); + MarkerOverview(int height, QWidget *parent = nullptr); + virtual void update() = 0; + protected: void resizeEvent(QResizeEvent *event); -private: + int height; - Sphere *sphere; QGraphicsScene scene; QGraphicsPixmapItem *img_item = nullptr; +}; + +class SphereOverview: public MarkerOverview { + Q_OBJECT +public: + SphereOverview(QPointF center, double radius, int height, QWidget *parent = nullptr); + virtual void update(); + + QPointF center; + double radius; + +private: QGraphicsEllipseItem *ellipse = nullptr; }; -class ReflectionView: public QGraphicsView { +class AlignOverview: public MarkerOverview { + Q_OBJECT +public: + AlignOverview(QRectF rect, int height, QWidget *parent = nullptr); + virtual void update(); + QRectF rect; + +private: + QGraphicsRectItem *item = nullptr; +}; + +class ReflectionOverview: public QGraphicsView { Q_OBJECT public: double lightRadius = 2.0; - ReflectionView(Sphere *sphere, int height, QWidget *parent = nullptr); - ~ReflectionView(); + ReflectionOverview(Sphere *sphere, int height, QWidget *parent = nullptr); + ~ReflectionOverview(); void init(); //call this when the sphere changes position void update(); //this when detecting highlights. -//public slots: + //public slots: protected: void resizeEvent(QResizeEvent *event); diff --git a/relightlab/roadmap.md b/relightlab/roadmap.md index 6ae80391..63fc1d99 100644 --- a/relightlab/roadmap.md +++ b/relightlab/roadmap.md @@ -13,9 +13,7 @@ * ellipse reflections geometrically accurate * cancel button on sphere reflection processing. * better info on queue items. -* if scale exists don't overwrite imageWith with dome scale. * remove relight_vector and jus use eigen. -* settings: notifications * allow resize for normals integration (it's too slow...). ## Long term new features @@ -38,6 +36,7 @@ * check for invalid inner circle when creating a sphere. * test pause/stop/play in queue. * deal with #lights different from #images +* when the sphere changes size, the icon with the reflection overview is not resized properly ## Small Bugs diff --git a/relightlab/sphererow.cpp b/relightlab/sphererow.cpp index 894a6ee0..628913e9 100644 --- a/relightlab/sphererow.cpp +++ b/relightlab/sphererow.cpp @@ -49,12 +49,12 @@ SphereRow::SphereRow(Sphere *_sphere, QWidget *parent): QWidget(parent) { QHBoxLayout *columns = new QHBoxLayout(this); columns->setSpacing(20); - position = new PositionView(sphere, rowHeight); + position = new SphereOverview(sphere->center, sphere->radius, rowHeight); position->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); columns->addWidget(position); - reflections = new ReflectionView(sphere, rowHeight); + reflections = new ReflectionOverview(sphere, rowHeight); reflections->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); columns->addWidget(reflections); @@ -79,6 +79,9 @@ void SphereRow::edit() { sphere_dialog->setSphere(sphere); int answer = sphere_dialog->exec(); if(answer == QDialog::Accepted) { + position->center = sphere->center; + position->radius = sphere->radius; + position->update(); reflections->init(); detectHighlights(); diff --git a/relightlab/sphererow.h b/relightlab/sphererow.h index c6884f18..2a58541b 100644 --- a/relightlab/sphererow.h +++ b/relightlab/sphererow.h @@ -9,8 +9,8 @@ class Sphere; class QLabel; class QProgressBar; -class ReflectionView; -class PositionView; +class ReflectionOverview; +class SphereOverview; class DetectHighlights: public Task { public: @@ -25,10 +25,10 @@ class DetectHighlights: public Task { class SphereRow: public QWidget { Q_OBJECT public: - Sphere *sphere; int rowHeight = 92; - PositionView *position; - ReflectionView *reflections; + Sphere *sphere = nullptr; + SphereOverview *position = nullptr; + ReflectionOverview *reflections = nullptr; QLabel *status = nullptr; QProgressBar *progress = nullptr; DetectHighlights *detect_highlights = nullptr; diff --git a/src/align.cpp b/src/align.cpp index e2b15281..8a92e851 100644 --- a/src/align.cpp +++ b/src/align.cpp @@ -38,3 +38,9 @@ void Align::fromJson(QJsonObject obj) { offsets.push_back(QPointF(j[0].toDouble(), j[1].toDouble())); } } + +void Align::readThumb(QImage img, int n) { + if(n == 0) + thumbs.clear(); + thumbs.push_back(img.copy(rect)); +} diff --git a/src/align.h b/src/align.h index 750094cb..cb312ca3 100644 --- a/src/align.h +++ b/src/align.h @@ -1,6 +1,7 @@ #ifndef ALIGN_H #define ALIGN_H +#include #include #include #include @@ -16,9 +17,11 @@ class Align { QRect rect; std::vector offsets; //from the center of the rect + std::vector thumbs; QJsonObject toJson(); void fromJson(QJsonObject obj); + void readThumb(QImage img, int n); }; #endif // ALIGN_H