Gui: interactive image scaling:
* add option to allow points outside of image * after starting the interactive scaling allow to cancel it immediately
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
# include <QDialog>
|
||||
# include <QPushButton>
|
||||
# include <map>
|
||||
# include <Inventor/SoPickedPoint.h>
|
||||
# include <Inventor/events/SoLocation2Event.h>
|
||||
# include <Inventor/events/SoMouseButtonEvent.h>
|
||||
# include <Inventor/nodes/SoBaseColor.h>
|
||||
@@ -136,8 +137,6 @@ void TaskImageScale::selectedPoints(size_t num)
|
||||
else if (num == 2) {
|
||||
ui->labelInstruction->setText(tr("Enter desired distance between the points"));
|
||||
ui->pushButtonScale->setEnabled(true);
|
||||
ui->pushButtonScale->setText(tr("Accept"));
|
||||
ui->pushButtonCancel->show();
|
||||
ui->quantitySpinBox->setEnabled(true);
|
||||
ui->quantitySpinBox->setValue(scale->getDistance());
|
||||
}
|
||||
@@ -158,10 +157,17 @@ void TaskImageScale::scaleImage(double factor)
|
||||
|
||||
void TaskImageScale::startScale()
|
||||
{
|
||||
scale->activate();
|
||||
ui->labelInstruction->setText(tr("Select two points in the 3d view"));
|
||||
scale->activate(ui->checkBoxOutside->isChecked());
|
||||
if (ui->checkBoxOutside->isChecked()) {
|
||||
ui->labelInstruction->setText(tr("Select two points in the 3d view"));
|
||||
}
|
||||
else {
|
||||
ui->labelInstruction->setText(tr("Select two points on the image"));
|
||||
}
|
||||
ui->checkBoxOutside->setEnabled(false);
|
||||
ui->pushButtonScale->setEnabled(false);
|
||||
ui->pushButtonCancel->hide();
|
||||
ui->pushButtonScale->setText(tr("Accept"));
|
||||
ui->pushButtonCancel->show();
|
||||
ui->quantitySpinBox->setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -175,9 +181,11 @@ void TaskImageScale::rejectScale()
|
||||
{
|
||||
scale->deactivate();
|
||||
ui->labelInstruction->clear();
|
||||
ui->pushButtonScale->setEnabled(true);
|
||||
ui->pushButtonScale->setText(tr("Interactive"));
|
||||
ui->pushButtonCancel->hide();
|
||||
ui->quantitySpinBox->setEnabled(false);
|
||||
ui->checkBoxOutside->setEnabled(true);
|
||||
|
||||
scale->clearPoints();
|
||||
}
|
||||
@@ -187,7 +195,8 @@ void TaskImageScale::onInteractiveScale()
|
||||
if (!feature.expired() && !scale) {
|
||||
View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
scale = new InteractiveScale(viewer);
|
||||
auto vp = Application::Instance->getViewProvider(feature.get());
|
||||
scale = new InteractiveScale(viewer, vp);
|
||||
connect(scale, &InteractiveScale::selectedPoints,
|
||||
this, &TaskImageScale::selectedPoints);
|
||||
}
|
||||
@@ -205,9 +214,11 @@ void TaskImageScale::onInteractiveScale()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
InteractiveScale::InteractiveScale(View3DInventorViewer* view)
|
||||
InteractiveScale::InteractiveScale(View3DInventorViewer* view, ViewProvider* vp)
|
||||
: active{false}
|
||||
, allowOutsideImage{false}
|
||||
, viewer{view}
|
||||
, viewProv{vp}
|
||||
{
|
||||
coords = new SoCoordinate3;
|
||||
coords->ref();
|
||||
@@ -228,7 +239,7 @@ InteractiveScale::~InteractiveScale()
|
||||
root->unref();
|
||||
}
|
||||
|
||||
void InteractiveScale::activate()
|
||||
void InteractiveScale::activate(bool allowOutside)
|
||||
{
|
||||
if (viewer) {
|
||||
static_cast<SoSeparator*>(viewer->getSceneGraph())->addChild(root);
|
||||
@@ -238,6 +249,7 @@ void InteractiveScale::activate()
|
||||
viewer->setSelectionEnabled(false);
|
||||
viewer->getWidget()->setCursor(QCursor(Qt::CrossCursor));
|
||||
active = true;
|
||||
allowOutsideImage = allowOutside;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,33 +288,67 @@ void InteractiveScale::clearPoints()
|
||||
coords->point.setNum(0);
|
||||
}
|
||||
|
||||
void InteractiveScale::findPointOnPlane(SoEventCallback * ecb)
|
||||
{
|
||||
if (allowOutsideImage) {
|
||||
findPointOnFocalPlane(ecb);
|
||||
}
|
||||
else {
|
||||
findPointOnImagePlane(ecb);
|
||||
}
|
||||
}
|
||||
|
||||
void InteractiveScale::findPointOnImagePlane(SoEventCallback * ecb)
|
||||
{
|
||||
const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent *>(ecb->getEvent());
|
||||
Gui::View3DInventorViewer* view = static_cast<Gui::View3DInventorViewer*>(ecb->getUserData());
|
||||
std::unique_ptr<SoPickedPoint> pp(view->getPointOnRay(mbe->getPosition(), viewProv));
|
||||
if (pp.get()) {
|
||||
auto pos3d = pp->getPoint();
|
||||
|
||||
collectPoint(pos3d);
|
||||
}
|
||||
}
|
||||
|
||||
void InteractiveScale::findPointOnFocalPlane(SoEventCallback * ecb)
|
||||
{
|
||||
const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent *>(ecb->getEvent());
|
||||
Gui::View3DInventorViewer* view = static_cast<Gui::View3DInventorViewer*>(ecb->getUserData());
|
||||
|
||||
auto pos2d = mbe->getPosition();
|
||||
auto pos3d = view->getPointOnFocalPlane(pos2d);
|
||||
|
||||
collectPoint(pos3d);
|
||||
}
|
||||
|
||||
void InteractiveScale::collectPoint(const SbVec3f& pos3d)
|
||||
{
|
||||
if (points.empty()) {
|
||||
points.push_back(pos3d);
|
||||
coords->point.set1Value(0, pos3d);
|
||||
}
|
||||
else if (points.size() == 1) {
|
||||
double distance = getDistance(pos3d);
|
||||
if (distance > Base::Precision::Confusion()) {
|
||||
points.push_back(pos3d);
|
||||
coords->point.set1Value(1, pos3d);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning(std::string("Image scale"), "The second point is too close. Retry!\n");
|
||||
}
|
||||
}
|
||||
|
||||
Q_EMIT selectedPoints(points.size());
|
||||
}
|
||||
|
||||
void InteractiveScale::getMouseClick(void * ud, SoEventCallback * ecb)
|
||||
{
|
||||
InteractiveScale* scale = static_cast<InteractiveScale*>(ud);
|
||||
const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent *>(ecb->getEvent());
|
||||
Gui::View3DInventorViewer* view = static_cast<Gui::View3DInventorViewer*>(ecb->getUserData());
|
||||
|
||||
if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
|
||||
ecb->setHandled();
|
||||
auto pos2d = mbe->getPosition();
|
||||
auto pos3d = view->getPointOnFocalPlane(pos2d);
|
||||
|
||||
if (scale->points.empty()) {
|
||||
scale->points.push_back(pos3d);
|
||||
scale->coords->point.set1Value(0, pos3d);
|
||||
}
|
||||
else if (scale->points.size() == 1) {
|
||||
double distance = scale->getDistance(pos3d);
|
||||
if (distance > Base::Precision::Confusion()) {
|
||||
scale->points.push_back(pos3d);
|
||||
scale->coords->point.set1Value(1, pos3d);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning(std::string("Image scale"), "The second point is too close. Retry!\n");
|
||||
}
|
||||
}
|
||||
|
||||
Q_EMIT scale->selectedPoints(scale->points.size());
|
||||
scale->findPointOnPlane(ecb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,14 +40,15 @@ class SoLineSet;
|
||||
namespace Gui {
|
||||
|
||||
class View3DInventorViewer;
|
||||
class ViewProvider;
|
||||
class InteractiveScale : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InteractiveScale(View3DInventorViewer* view);
|
||||
explicit InteractiveScale(View3DInventorViewer* view, ViewProvider* vp);
|
||||
~InteractiveScale();
|
||||
void activate();
|
||||
void activate(bool allowOutside);
|
||||
void deactivate();
|
||||
bool isActive() const {
|
||||
return active;
|
||||
@@ -57,17 +58,23 @@ public:
|
||||
void clearPoints();
|
||||
|
||||
private:
|
||||
static void getMouseClick(void * ud, SoEventCallback * n);
|
||||
static void getMousePosition(void * ud, SoEventCallback * n);
|
||||
static void getMouseClick(void * ud, SoEventCallback * ecb);
|
||||
static void getMousePosition(void * ud, SoEventCallback * ecb);
|
||||
void findPointOnPlane(SoEventCallback * ecb);
|
||||
void findPointOnImagePlane(SoEventCallback * ecb);
|
||||
void findPointOnFocalPlane(SoEventCallback * ecb);
|
||||
void collectPoint(const SbVec3f&);
|
||||
|
||||
Q_SIGNALS:
|
||||
void selectedPoints(size_t);
|
||||
|
||||
private:
|
||||
bool active;
|
||||
bool allowOutsideImage;
|
||||
SoCoordinate3* coords;
|
||||
SoSeparator* root;
|
||||
QPointer<Gui::View3DInventorViewer> viewer;
|
||||
ViewProvider* viewProv;
|
||||
std::vector<SbVec3f> points;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>293</width>
|
||||
<height>266</height>
|
||||
<width>421</width>
|
||||
<height>267</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -115,6 +115,19 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxOutside">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Allow points outside the image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
@@ -157,6 +170,15 @@
|
||||
<header>Gui/QuantitySpinBox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>spinBoxWidth</tabstop>
|
||||
<tabstop>spinBoxHeight</tabstop>
|
||||
<tabstop>checkBoxRatio</tabstop>
|
||||
<tabstop>pushButtonScale</tabstop>
|
||||
<tabstop>pushButtonCancel</tabstop>
|
||||
<tabstop>checkBoxOutside</tabstop>
|
||||
<tabstop>quantitySpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user