diff --git a/doc/rel_notes/0.9.0.txt b/doc/rel_notes/0.9.0.txt index d74cd0e11..c2ab19ba3 100644 --- a/doc/rel_notes/0.9.0.txt +++ b/doc/rel_notes/0.9.0.txt @@ -87,6 +87,9 @@ Visualization Application * The GUI now accepts a list of files to be opened on the command line. + * Added options to the World and Camera view to visualize the landmarks seen + by the current camera. Those landmarks can also be colored and thresholded. + * Added a depth map view and a depth map visualisation in the world view. The depth maps can be thresholded directly in the world view, and the depth map view offers several visualisation modes such as depths, uniqueness ratios or diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index b1f8ad6e6..931d9226f 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -42,6 +42,7 @@ set(gui_ui FeatureOptions.ui ImageOptions.ui PointOptions.ui + VisibleLandmarksOptions.ui ) set(gui_resources @@ -67,6 +68,7 @@ set(gui_moc_headers MatchMatrixWindow.h PointOptions.h WorldView.h + VisibleLandmarksOptions.h tools/AbstractTool.h tools/BundleAdjustTool.h tools/CanonicalTransformTool.h @@ -93,6 +95,7 @@ set(gui_sources PointOptions.cxx Project.cxx WorldView.cxx + VisibleLandmarksOptions.cxx main.cxx vtkMaptkCamera.cxx vtkMaptkCameraRepresentation.cxx diff --git a/gui/CameraView.cxx b/gui/CameraView.cxx index db9d96a95..09b1a1676 100644 --- a/gui/CameraView.cxx +++ b/gui/CameraView.cxx @@ -202,6 +202,8 @@ class CameraViewPrivate LandmarkCloud landmarks; SegmentCloud residuals; + LandmarkCloud visibleLandmarks; + LandmarkCloud nonVisibleLandmarks; QHash landmarkData; @@ -248,7 +250,6 @@ CameraViewPrivate::PointCloud::PointCloud() void CameraViewPrivate::PointCloud::addPoint(double x, double y, double z) { auto const vid = this->points->InsertNextPoint(x, y, z); - this->verts->InsertNextCell(1); this->verts->InsertCellPoint(vid); @@ -375,6 +376,8 @@ void CameraViewPrivate::setTransforms(int imageHeight) this->featureRep->GetTrailsActor()->SetUserMatrix(xf.GetPointer()); this->landmarks.actor->SetUserMatrix(xf.GetPointer()); this->residuals.actor->SetUserMatrix(xf.GetPointer()); + this->visibleLandmarks.actor->SetUserMatrix(xf.GetPointer()); + this->nonVisibleLandmarks.actor->SetUserMatrix(xf.GetPointer()); } //----------------------------------------------------------------------------- @@ -428,6 +431,11 @@ CameraView::CameraView(QWidget* parent, Qt::WindowFlags flags) d->landmarkOptions->setDefaultColor(Qt::magenta); d->landmarkOptions->addActor(d->landmarks.actor.GetPointer()); d->landmarkOptions->addMapper(d->landmarks.mapper.GetPointer()); + d->landmarkOptions->addVisibleLandmarksActor(d->visibleLandmarks.actor.GetPointer()); + d->landmarkOptions->addNonVisibleLandmarksActor(d->nonVisibleLandmarks.actor.GetPointer()); + + d->visibleLandmarks.actor->SetVisibility(d->landmarkOptions->isVisibleLandmarksChecked()); + d->nonVisibleLandmarks.actor->SetVisibility(false); d->setPopup(d->UI.actionShowLandmarks, d->landmarkOptions); @@ -465,6 +473,9 @@ CameraView::CameraView(QWidget* parent, Qt::WindowFlags flags) connect(d->UI.actionShowResiduals, SIGNAL(toggled(bool)), this, SLOT(setResidualsVisible(bool))); + connect(d->landmarkOptions, SIGNAL(visibleLandmarksDisplayChanged(bool)), + this, SLOT(switchToVisibleLandmarksMode(bool))); + // Set up ortho view d->renderer->GetActiveCamera()->ParallelProjectionOn(); d->renderer->GetActiveCamera()->SetClippingRange(1.0, 3.0); @@ -484,6 +495,8 @@ CameraView::CameraView(QWidget* parent, Qt::WindowFlags flags) d->renderer->AddActor(d->featureRep->GetTrailsActor()); d->renderer->AddActor(d->landmarks.actor.GetPointer()); d->renderer->AddActor(d->residuals.actor.GetPointer()); + d->renderer->AddActor(d->visibleLandmarks.actor.GetPointer()); + d->renderer->AddActor(d->nonVisibleLandmarks.actor.GetPointer()); d->renderer->AddViewProp(d->imageActor.GetPointer()); d->imageActor->SetPosition(0.0, 0.0, -0.5); @@ -621,6 +634,25 @@ void CameraView::addLandmark( d->UI.renderWidget->update(); } +//----------------------------------------------------------------------------- +void CameraView::addVisibleLandmark( + kwiver::vital::landmark_id_t id, double x, double y) +{ + QTE_D(); + + d->visibleLandmarks.addPoint(x, y, 1.0, d->landmarkData.value(id)); + d->UI.renderWidget->update(); +} + +//----------------------------------------------------------------------------- +void CameraView::addNonVisibleLandmark(kwiver::vital::landmark_id_t id, double x, double y) +{ + QTE_D(); + + d->nonVisibleLandmarks.addPoint(x, y, 1.0, d->landmarkData.value(id)); + d->UI.renderWidget->update(); +} + //----------------------------------------------------------------------------- void CameraView::addResidual( kwiver::vital::track_id_t id, double x1, double y1, double x2, double y2) @@ -648,6 +680,30 @@ void CameraView::clearResiduals() d->residuals.clear(); } +//----------------------------------------------------------------------------- +void CameraView::setVisibleLandmarksVisibleOnly(bool state) +{ + QTE_D(); + + d->landmarks.actor->SetVisibility(!state); + + d->UI.renderWidget->update(); +} + +//----------------------------------------------------------------------------- +void CameraView::clearVisibleLandmarks() +{ + QTE_D(); + d->visibleLandmarks.clear(); +} + +//----------------------------------------------------------------------------- +void CameraView::clearNonVisibleLandmarks() +{ + QTE_D(); + d->nonVisibleLandmarks.clear(); +} + //----------------------------------------------------------------------------- void CameraView::setImageVisible(bool state) { @@ -662,7 +718,26 @@ void CameraView::setLandmarksVisible(bool state) { QTE_D(); - d->landmarks.actor->SetVisibility(state); + if(d->landmarkOptions->isVisibleLandmarksChecked()) + { + d->visibleLandmarks.actor->SetVisibility(state); + d->nonVisibleLandmarks.actor->SetVisibility(state && !d->landmarkOptions-> + isVisibleLandmarksOnlyChecked()); + } + else + { + d->landmarks.actor->SetVisibility(state); + } + + d->UI.renderWidget->update(); +} + +//----------------------------------------------------------------------------- +void CameraView::setVisibleLandmarksVisible(bool state) +{ + QTE_D(); + + d->visibleLandmarks.actor->SetVisibility(state); d->UI.renderWidget->update(); } @@ -718,4 +793,17 @@ void CameraView::updateFeatures() } } +//----------------------------------------------------------------------------- +void CameraView::switchToVisibleLandmarksMode(bool state) +{ + QTE_D(); + + d->landmarks.actor->SetVisibility(!state); + d->visibleLandmarks.actor->SetVisibility(state); + d->nonVisibleLandmarks.actor->SetVisibility(state && !d->landmarkOptions-> + isVisibleLandmarksOnlyChecked()); + + d->UI.renderWidget->update(); +} + //END CameraView diff --git a/gui/CameraView.h b/gui/CameraView.h index 8c3ed78ce..1562826cd 100644 --- a/gui/CameraView.h +++ b/gui/CameraView.h @@ -67,23 +67,35 @@ public slots: void setActiveFrame(unsigned); void addLandmark(kwiver::vital::landmark_id_t id, double x, double y); + + void addVisibleLandmark(kwiver::vital::landmark_id_t id, double x, double y); + + void addNonVisibleLandmark(kwiver::vital::landmark_id_t id, double x, double y); + void addResidual(kwiver::vital::track_id_t id, double x1, double y1, double x2, double y2); void clearLandmarks(); + void clearVisibleLandmarks(); + void clearNonVisibleLandmarks(); void clearResiduals(); + void setVisibleLandmarksVisibleOnly(bool); + void resetView(); void resetViewToFullExtents(); protected slots: void setImageVisible(bool); void setLandmarksVisible(bool); + void setVisibleLandmarksVisible(bool); void setResidualsVisible(bool); void updateFeatures(); + void switchToVisibleLandmarksMode(bool); + private: QTE_DECLARE_PRIVATE_RPTR(CameraView) QTE_DECLARE_PRIVATE(CameraView) diff --git a/gui/CameraView.ui b/gui/CameraView.ui index d2d3f5cd6..e64c145dd 100644 --- a/gui/CameraView.ui +++ b/gui/CameraView.ui @@ -6,15 +6,24 @@ 0 0 - 595 - 300 + 654 + 302 Form - + + 0 + + + 0 + + + 0 + + 0 diff --git a/gui/MainWindow.cxx b/gui/MainWindow.cxx index d98c6b432..f4441f6ed 100644 --- a/gui/MainWindow.cxx +++ b/gui/MainWindow.cxx @@ -223,6 +223,9 @@ class MainWindowPrivate QString imagePath; // Full path to camera image data QString depthMapPath; // Full path to depth map data + kwiver::vital::landmark_map::map_landmark_t *visibleLandmarks; + kwiver::vital::landmark_map::map_landmark_t *nonVisibleLandmarks; + bool areVisibleLandmarksLoaded = false; }; // Methods @@ -340,6 +343,10 @@ void MainWindowPrivate::addFrame( cd.imagePath = imagePath; + + cd.visibleLandmarks = new kwiver::vital::landmark_map::map_landmark_t(); + cd.nonVisibleLandmarks = new kwiver::vital::landmark_map::map_landmark_t(); + if (camera) { this->orphanImages.clear(); @@ -423,8 +430,42 @@ void MainWindowPrivate::setActiveCamera(int id) { this->activeCameraIndex = id; this->UI.worldView->setActiveCamera(this->cameras[id].camera); + + //Load visible landmarks for the active camera once + if(!this->cameras[id].areVisibleLandmarksLoaded) + { + + *this->cameras[id].nonVisibleLandmarks = landmarks->landmarks(); + + auto const& tracks = this->tracks->tracks(); + foreach (auto const& track, tracks) + { + if (track->find(id) != track->end()) + { + auto const& landmarkId = track->id(); + auto const& landmark = this->landmarks->landmarks()[landmarkId]; + + if (landmark) + { + this->cameras[id].visibleLandmarks->insert( + std::make_pair(landmarkId, landmark)); + this->cameras[id].nonVisibleLandmarks->erase(landmarkId); + } + } + } + + this->cameras[id].areVisibleLandmarksLoaded = true; + } + this->updateCameraView(); + this->UI.worldView->setVisibleLandmarks(kwiver::vital::simple_landmark_map( + *this->cameras[id].visibleLandmarks)); + + + this->UI.worldView->setNonVisibleLandmarks(kwiver::vital::simple_landmark_map( + *this->cameras[id].nonVisibleLandmarks)); + auto& cd = this->cameras[id]; if (!cd.depthMapPath.isEmpty()) { @@ -502,6 +543,25 @@ void MainWindowPrivate::updateCameraView() } } } + + // Show landmarks visible by the current camera + this->UI.cameraView->clearVisibleLandmarks(); + foreach (auto const& landmark, *this->cameras[this->activeCameraIndex].visibleLandmarks) + { + auto coord = landmark.second->loc(); + double pp[2]; + this->cameras[this->activeCameraIndex].camera->ProjectPoint(coord,pp); + this->UI.cameraView->addVisibleLandmark(landmark.first,pp[0],pp[1]); + } + + this->UI.cameraView->clearNonVisibleLandmarks(); + foreach (auto const& landmark, *this->cameras[this->activeCameraIndex].nonVisibleLandmarks) + { + auto coord = landmark.second->loc(); + double pp[2]; + this->cameras[this->activeCameraIndex].camera->ProjectPoint(coord,pp); + this->UI.cameraView->addNonVisibleLandmark(landmark.first,pp[0],pp[1]); + } } //----------------------------------------------------------------------------- diff --git a/gui/PointOptions.cxx b/gui/PointOptions.cxx index e41062326..d9c9ebda5 100644 --- a/gui/PointOptions.cxx +++ b/gui/PointOptions.cxx @@ -35,6 +35,7 @@ #include "DataColorOptions.h" #include "DataFilterOptions.h" #include "FieldInformation.h" +#include "VisibleLandmarksOptions.h" #include #include @@ -99,11 +100,14 @@ class PointOptionsPrivate DataColorOptions* dataColorOptions; DataFilterOptions* dataFilterOptions; + VisibleLandmarksOptions* visibleLandmarksOptions; QList actors; QList mappers; QHash filters; + vtkActor* nonVisibleLandmarksActor; + QHash fields; QButtonGroup colorMode; @@ -249,6 +253,10 @@ PointOptions::PointOptions(QString const& settingsGroup, d->UI.dataFilterMenu->setText(d->dataFilterOptions->iconText() + " "); d->filterState = Qt::Unchecked; + d->visibleLandmarksOptions = + new VisibleLandmarksOptions(settingsGroup+"VsibleLandmarksOptions", this); + d->setPopup(d->UI.visibleLandmarksMenu, d->visibleLandmarksOptions); + // Set up option persistence d->uiState.setCurrentGroup(settingsGroup); @@ -275,6 +283,18 @@ PointOptions::PointOptions(QString const& settingsGroup, connect(&d->colorMode, SIGNAL(buttonClicked(int)), this, SLOT(setColorMode(int))); + connect(d->UI.showVisibleLandmarks, SIGNAL(toggled(bool)), + this, SIGNAL(visibleLandmarksDisplayChanged(bool))); + + connect(d->UI.showVisibleLandmarks, SIGNAL(toggled(bool)), + d->UI.showVisibleLandmarksOnly, SLOT(setEnabled(bool))); + + connect(d->UI.showVisibleLandmarksOnly, SIGNAL(toggled(bool)), + this, SLOT(showVisibleLandmarksOnly(bool))); + + connect(d->visibleLandmarksOptions, SIGNAL(visibleLandmarksChanged()), + this, SIGNAL(modified())); + connect(d->dataColorOptions, SIGNAL(iconChanged(QIcon)), this, SLOT(setDataColorIcon(QIcon))); } @@ -332,6 +352,16 @@ void PointOptions::setDataFields( } } +//----------------------------------------------------------------------------- +void PointOptions::showVisibleLandmarksOnly(bool state) +{ + QTE_D(); + + d->nonVisibleLandmarksActor->SetVisibility(!state); + + emit this->modified(); +} + //----------------------------------------------------------------------------- void PointOptions::addActor(vtkActor* actor) { @@ -343,6 +373,23 @@ void PointOptions::addActor(vtkActor* actor) d->actors.append(actor); } +//----------------------------------------------------------------------------- +void PointOptions::addVisibleLandmarksActor(vtkActor *actor) +{ + QTE_D(); + + d->visibleLandmarksOptions->addActor(actor); +} + +//----------------------------------------------------------------------------- +void PointOptions::addNonVisibleLandmarksActor(vtkActor * actor) +{ + QTE_D(); + + d->nonVisibleLandmarksActor = actor; + addActor(actor); +} + //----------------------------------------------------------------------------- void PointOptions::addMapper(vtkMapper* mapper) { @@ -353,6 +400,22 @@ void PointOptions::addMapper(vtkMapper* mapper) d->mappers.append(mapper); } +//----------------------------------------------------------------------------- +bool PointOptions::isVisibleLandmarksChecked() +{ + QTE_D(); + + return d->UI.showVisibleLandmarks->isChecked(); +} + +//----------------------------------------------------------------------------- +bool PointOptions::isVisibleLandmarksOnlyChecked() +{ + QTE_D(); + + return d->UI.showVisibleLandmarksOnly->isChecked(); +} + //----------------------------------------------------------------------------- void PointOptions::setSize(int size) { diff --git a/gui/PointOptions.h b/gui/PointOptions.h index 8c6164c83..f1a1f1801 100644 --- a/gui/PointOptions.h +++ b/gui/PointOptions.h @@ -52,16 +52,24 @@ class PointOptions : public QWidget virtual ~PointOptions(); void addActor(vtkActor*); + void addVisibleLandmarksActor(vtkActor*); + void addNonVisibleLandmarksActor(vtkActor*); void addMapper(vtkMapper*); + bool isVisibleLandmarksChecked(); + bool isVisibleLandmarksOnlyChecked(); + void setDefaultColor(QColor const&); public slots: void setTrueColorAvailable(bool); void setDataFields(QHash const&); + void showVisibleLandmarksOnly(bool); signals: void modified(); + void visibleLandmarksDisplayChanged(bool); + void visibleLandmarksOnlyDisplayChanged(bool); protected slots: void setSize(int); diff --git a/gui/PointOptions.ui b/gui/PointOptions.ui index 357dbb03e..cc8a4fd0e 100644 --- a/gui/PointOptions.ui +++ b/gui/PointOptions.ui @@ -6,17 +6,14 @@ 0 0 - 207 - 169 + 305 + 271 Form - - QFormLayout::AllNonFixedFieldsGrow - @@ -57,7 +54,7 @@ - + 255 255 @@ -127,7 +124,7 @@ - + @@ -157,6 +154,46 @@ + + + + + + Show visible landmarks + + + + + + + true + + + + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextOnly + + + true + + + + + + + + + false + + + Show visible landmarks only + + + diff --git a/gui/VisibleLandmarksOptions.cxx b/gui/VisibleLandmarksOptions.cxx new file mode 100644 index 000000000..607b95c94 --- /dev/null +++ b/gui/VisibleLandmarksOptions.cxx @@ -0,0 +1,174 @@ +/*ckwg +29 + * Copyright 2016 by Kitware, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name Kitware, Inc. nor the names of any contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "VisibleLandmarksOptions.h" + +#include "ui_VisibleLandmarksOptions.h" + +#include "DataColorOptions.h" +#include "DataFilterOptions.h" +#include "FieldInformation.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace +{ + +//----------------------------------------------------------------------------- +enum ColorMode +{ + SolidColor, + TrueColor, + DataColor, +}; + +//----------------------------------------------------------------------------- +template +Container sorted(Container c) +{ + qSort(c); + return c; +} + +} + +/////////////////////////////////////////////////////////////////////////////// + +//BEGIN VisibleLandmarksOptionsPrivate + +QTE_IMPLEMENT_D_FUNC(VisibleLandmarksOptions) + +//----------------------------------------------------------------------------- +class VisibleLandmarksOptionsPrivate +{ +public: + + Ui::VisibleLandmarksOptions UI; + qtUiState uiState; + + vtkActor* actor; + +}; + +//END VisibleLandmarksOptionsPrivate + +/////////////////////////////////////////////////////////////////////////////// + +//BEGIN VisibleLandmarksOptions + +//----------------------------------------------------------------------------- +VisibleLandmarksOptions::VisibleLandmarksOptions(QString const& settingsGroup, + QWidget* parent, Qt::WindowFlags flags) + : QWidget(parent, flags), d_ptr(new VisibleLandmarksOptionsPrivate) +{ + QTE_D(); + + // Set up UI + d->UI.setupUi(this); + + // Set up option persistence + d->uiState.setCurrentGroup(settingsGroup); + + d->UI.color->persist(d->uiState, "Color"); + + auto const sizeItem = new qtUiState::Item( + d->UI.size, &QSlider::value, &QSlider::setValue); + d->uiState.map("Size", sizeItem); + + d->uiState.restore(); + + // Connect signals/slots + connect(d->UI.size, SIGNAL(valueChanged(int)), this, SLOT(setSize(int))); + connect(d->UI.color, SIGNAL(colorChanged(QColor)), this, SIGNAL(visibleLandmarksChanged())); +} + +//----------------------------------------------------------------------------- +VisibleLandmarksOptions::~VisibleLandmarksOptions() +{ + QTE_D(); + d->uiState.save(); +} + +//----------------------------------------------------------------------------- +void VisibleLandmarksOptions::setDefaultColor(QColor const& color) +{ + QTE_D(); + + d->UI.color->setColor(color); + d->uiState.restore(); +} + +//----------------------------------------------------------------------------- +void VisibleLandmarksOptions::setVisibility(bool state) +{ + QTE_D(); + + d->actor->SetVisibility(state); + + emit this->visibleLandmarksChanged(); +} + +//----------------------------------------------------------------------------- +void VisibleLandmarksOptions::addActor(vtkActor* actor) +{ + QTE_D(); + + d->UI.color->addActor(actor); + actor->GetProperty()->SetPointSize(d->UI.size->value()); + + d->actor = actor; +} + +//----------------------------------------------------------------------------- +void VisibleLandmarksOptions::setSize(int size) +{ + QTE_D(); + + d->actor->GetProperty()->SetPointSize(size); + + emit this->visibleLandmarksChanged(); +} + +//END VisibleLandmarksOptions diff --git a/gui/VisibleLandmarksOptions.h b/gui/VisibleLandmarksOptions.h new file mode 100644 index 000000000..36490bdcf --- /dev/null +++ b/gui/VisibleLandmarksOptions.h @@ -0,0 +1,74 @@ +/*ckwg +29 + * Copyright 2016 by Kitware, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name Kitware, Inc. nor the names of any contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef VISIBLELANDMARKSOPTIONS_H +#define VISIBLELANDMARKSOPTIONS_H + +#include + +#include + +class vtkActor; + +struct FieldInformation; + +class VisibleLandmarksOptionsPrivate; + +class VisibleLandmarksOptions : public QWidget +{ + Q_OBJECT + +public: + explicit VisibleLandmarksOptions(QString const& settingsGroup, + QWidget* parent = 0, Qt::WindowFlags flags = 0); + virtual ~VisibleLandmarksOptions(); + + void addActor(vtkActor*); + + void setDefaultColor(QColor const&); + +public slots: + void setVisibility(bool); + +signals: + void modified(); + void visibleLandmarksChanged(); + +protected slots: + void setSize(int); + +private: + QTE_DECLARE_PRIVATE_RPTR(VisibleLandmarksOptions) + QTE_DECLARE_PRIVATE(VisibleLandmarksOptions) + + QTE_DISABLE_COPY(VisibleLandmarksOptions) +}; + +#endif diff --git a/gui/VisibleLandmarksOptions.ui b/gui/VisibleLandmarksOptions.ui new file mode 100644 index 000000000..efad53cfa --- /dev/null +++ b/gui/VisibleLandmarksOptions.ui @@ -0,0 +1,66 @@ + + + VisibleLandmarksOptions + + + + 0 + 0 + 142 + 75 + + + + Form + + + + + + Size + + + + + + + Qt::Horizontal + + + + + + + Color + + + + + + + + 255 + 255 + 255 + + + + + + + + + qtColorButton + QPushButton +
qtColorButton.h
+
+ + ActorColorButton + qtColorButton +
ActorColorButton.h
+ 1 +
+
+ + +
diff --git a/gui/WorldView.cxx b/gui/WorldView.cxx index 6911d232f..b2111960a 100644 --- a/gui/WorldView.cxx +++ b/gui/WorldView.cxx @@ -129,6 +129,22 @@ class WorldViewPrivate vtkNew landmarkMapper; vtkNew landmarkActor; + vtkNew visibleLandmarkPoints; + vtkNew visibleLandmarkVerts; + vtkNew visibleLandmarkElevations; + vtkNew visibleLandmarkColors; + vtkNew visibleLandmarkObservations; + vtkNew visibleLandmarkMapper; + vtkNew visibleLandmarkActor; + + vtkNew nonVisibleLandmarkPoints; + vtkNew nonVisibleLandmarkVerts; + vtkNew nonVisibleLandmarkElevations; + vtkNew nonVisibleLandmarkColors; + vtkNew nonVisibleLandmarkObservations; + vtkNew nonVisibleLandmarkMapper; + vtkNew nonVisibleLandmarkActor; + vtkNew imageActor; vtkNew emptyImage; @@ -140,6 +156,7 @@ class WorldViewPrivate ImageOptions* imageOptions; CameraOptions* cameraOptions; PointOptions* landmarkOptions; + PointOptions* visibleLandmarkOptions; DepthMapOptions* depthMapOptions; vtkNew imageProjection; @@ -311,11 +328,15 @@ WorldView::WorldView(QWidget* parent, Qt::WindowFlags flags) d->landmarkOptions = new PointOptions("WorldView/Landmarks", this); d->landmarkOptions->addActor(d->landmarkActor.GetPointer()); + d->landmarkOptions->addNonVisibleLandmarksActor(d->nonVisibleLandmarkActor.GetPointer()); + d->landmarkOptions->addVisibleLandmarksActor(d->visibleLandmarkActor.GetPointer()); d->setPopup(d->UI.actionShowLandmarks, d->landmarkOptions); connect(d->landmarkOptions, SIGNAL(modified()), d->UI.renderWidget, SLOT(update())); + d->visibleLandmarkActor->SetVisibility(d->landmarkOptions->isVisibleLandmarksChecked()); + d->depthMapOptions = new DepthMapOptions("WorldView/DepthMap", this); d->setPopup(d->UI.actionShowDepthMap, d->depthMapOptions); @@ -363,6 +384,9 @@ WorldView::WorldView(QWidget* parent, Qt::WindowFlags flags) connect(d->UI.actionShowDepthMap, SIGNAL(toggled(bool)), this, SLOT(setDepthMapVisible(bool))); + connect(d->landmarkOptions, SIGNAL(visibleLandmarksDisplayChanged(bool)), + this, SLOT(switchToVisibleLandmarksMode(bool))); + // Set up render pipeline d->renderer->SetBackground(0, 0, 0); d->renderWindow->AddRenderer(d->renderer.GetPointer()); @@ -409,6 +433,55 @@ WorldView::WorldView(QWidget* parent, Qt::WindowFlags flags) d->landmarkOptions->addMapper(d->landmarkMapper.GetPointer()); + // Set up visible landmarks actor + vtkNew visibleLandmarkPolyData; + + auto const visibleLandmarkPointData = visibleLandmarkPolyData->GetPointData(); + + d->visibleLandmarkColors->SetName(TrueColor); + d->visibleLandmarkColors->SetNumberOfComponents(3); + + d->visibleLandmarkElevations->SetName(Elevation); + d->visibleLandmarkElevations->SetNumberOfComponents(1); + + d->visibleLandmarkObservations->SetName(Observations); + d->visibleLandmarkObservations->SetNumberOfComponents(1); + + visibleLandmarkPolyData->SetPoints(d->visibleLandmarkPoints.GetPointer()); + visibleLandmarkPolyData->SetVerts(d->visibleLandmarkVerts.GetPointer()); + visibleLandmarkPointData->AddArray(d->visibleLandmarkColors.GetPointer()); + visibleLandmarkPointData->AddArray(d->visibleLandmarkElevations.GetPointer()); + visibleLandmarkPointData->AddArray(d->visibleLandmarkObservations.GetPointer()); + d->visibleLandmarkMapper->SetInputData(visibleLandmarkPolyData.GetPointer()); + + d->visibleLandmarkActor->SetMapper(d->visibleLandmarkMapper.GetPointer()); + d->renderer->AddActor(d->visibleLandmarkActor.GetPointer()); + + // Set up non-visible landmarks actor + vtkNew nonVisibleLandmarkPolyData; + + auto const nonVisibleLandmarkPointData = nonVisibleLandmarkPolyData->GetPointData(); + + d->nonVisibleLandmarkColors->SetName(TrueColor); + d->visibleLandmarkColors->SetNumberOfComponents(3); + + d->nonVisibleLandmarkElevations->SetName(Elevation); + d->nonVisibleLandmarkElevations->SetNumberOfComponents(1); + + d->nonVisibleLandmarkObservations->SetName(Observations); + d->nonVisibleLandmarkObservations->SetNumberOfComponents(1); + + nonVisibleLandmarkPolyData->SetPoints(d->nonVisibleLandmarkPoints.GetPointer()); + nonVisibleLandmarkPolyData->SetVerts(d->nonVisibleLandmarkVerts.GetPointer()); + nonVisibleLandmarkPointData->AddArray(d->nonVisibleLandmarkColors.GetPointer()); + nonVisibleLandmarkPointData->AddArray(d->nonVisibleLandmarkElevations.GetPointer()); + nonVisibleLandmarkPointData->AddArray(d->nonVisibleLandmarkObservations.GetPointer()); + d->nonVisibleLandmarkMapper->SetInputData(nonVisibleLandmarkPolyData.GetPointer()); + + d->nonVisibleLandmarkActor->SetMapper(d->nonVisibleLandmarkMapper.GetPointer()); + d->nonVisibleLandmarkActor->SetVisibility(false); + d->renderer->AddActor(d->nonVisibleLandmarkActor.GetPointer()); + // Set up ground plane grid d->groundPlane->SetOrigin(-10.0, -10.0, 0.0); d->groundPlane->SetPoint1(+10.0, -10.0, 0.0); @@ -713,6 +786,132 @@ void WorldView::setLandmarks(kwiver::vital::landmark_map const& lm) d->updateAxes(this); } +//----------------------------------------------------------------------------- +void WorldView::setVisibleLandmarks(kwiver::vital::landmark_map const& lm) +{ + QTE_D(); + + auto const& landmarks = lm.landmarks(); + auto const size = static_cast(landmarks.size()); + + auto const defaultColor = kwiver::vital::rgb_color{}; + auto haveColor = false; + auto maxObservations = unsigned{0}; + auto minZ = qInf(), maxZ = -qInf(); + + d->visibleLandmarkPoints->Reset(); + d->visibleLandmarkVerts->Reset(); + d->visibleLandmarkColors->Reset(); + d->visibleLandmarkElevations->Reset(); + d->visibleLandmarkObservations->Reset(); + d->visibleLandmarkPoints->Allocate(size); + d->visibleLandmarkVerts->Allocate(size); + d->visibleLandmarkColors->Allocate(3 * size); + d->visibleLandmarkElevations->Allocate(size); + d->visibleLandmarkObservations->Allocate(size); + + vtkIdType vertIndex = 0; + foreach (auto const& lm, landmarks) + { + auto const& pos = lm.second->loc(); + auto const& color = lm.second->color(); + auto const observations = lm.second->observations(); + + d->visibleLandmarkPoints->InsertNextPoint(pos.data()); + d->visibleLandmarkVerts->InsertNextCell(1); + d->visibleLandmarkVerts->InsertCellPoint(vertIndex++); + d->visibleLandmarkColors->InsertNextValue(color.r); + d->visibleLandmarkColors->InsertNextValue(color.g); + d->visibleLandmarkColors->InsertNextValue(color.b); + d->visibleLandmarkElevations->InsertNextValue(pos[2]); + d->visibleLandmarkObservations->InsertNextValue(observations); + + haveColor = haveColor || (color != defaultColor); + maxObservations = qMax(maxObservations, observations); + minZ = qMin(minZ, pos[2]); + maxZ = qMax(maxZ, pos[2]); + } + + auto fields = QHash{}; + fields.insert("Elevation", FieldInformation{Elevation, {minZ, maxZ}}); + if (maxObservations) + { + auto const upper = static_cast(maxObservations); + fields.insert("Observations", FieldInformation{Observations, {0.0, upper}}); + } + + d->visibleLandmarkPoints->Modified(); + d->visibleLandmarkVerts->Modified(); + d->visibleLandmarkColors->Modified(); + d->visibleLandmarkObservations->Modified(); + + d->updateScale(this); + d->updateAxes(this); +} + +//----------------------------------------------------------------------------- +void WorldView::setNonVisibleLandmarks(kwiver::vital::landmark_map const& lm) +{ + QTE_D(); + + auto const& landmarks = lm.landmarks(); + auto const size = static_cast(landmarks.size()); + + auto const defaultColor = kwiver::vital::rgb_color{}; + auto haveColor = false; + auto maxObservations = unsigned{0}; + auto minZ = qInf(), maxZ = -qInf(); + + d->nonVisibleLandmarkPoints->Reset(); + d->nonVisibleLandmarkVerts->Reset(); + d->nonVisibleLandmarkColors->Reset(); + d->nonVisibleLandmarkElevations->Reset(); + d->nonVisibleLandmarkObservations->Reset(); + d->nonVisibleLandmarkPoints->Allocate(size); + d->nonVisibleLandmarkVerts->Allocate(size); + d->nonVisibleLandmarkColors->Allocate(3 * size); + d->nonVisibleLandmarkElevations->Allocate(size); + d->nonVisibleLandmarkObservations->Allocate(size); + + vtkIdType vertIndex = 0; + foreach (auto const& lm, landmarks) + { + auto const& pos = lm.second->loc(); + auto const& color = lm.second->color(); + auto const observations = lm.second->observations(); + + d->nonVisibleLandmarkPoints->InsertNextPoint(pos.data()); + d->nonVisibleLandmarkVerts->InsertNextCell(1); + d->nonVisibleLandmarkVerts->InsertCellPoint(vertIndex++); + d->nonVisibleLandmarkColors->InsertNextValue(color.r); + d->nonVisibleLandmarkColors->InsertNextValue(color.g); + d->nonVisibleLandmarkColors->InsertNextValue(color.b); + d->nonVisibleLandmarkElevations->InsertNextValue(pos[2]); + d->nonVisibleLandmarkObservations->InsertNextValue(observations); + + haveColor = haveColor || (color != defaultColor); + maxObservations = qMax(maxObservations, observations); + minZ = qMin(minZ, pos[2]); + maxZ = qMax(maxZ, pos[2]); + } + + auto fields = QHash{}; + fields.insert("Elevation", FieldInformation{Elevation, {minZ, maxZ}}); + if (maxObservations) + { + auto const upper = static_cast(maxObservations); + fields.insert("Observations", FieldInformation{Observations, {0.0, upper}}); + } + + d->nonVisibleLandmarkPoints->Modified(); + d->nonVisibleLandmarkVerts->Modified(); + d->nonVisibleLandmarkColors->Modified(); + d->nonVisibleLandmarkObservations->Modified(); + + d->updateScale(this); + d->updateAxes(this); +} + //----------------------------------------------------------------------------- void WorldView::setImageVisible(bool state) { @@ -735,7 +934,17 @@ void WorldView::setLandmarksVisible(bool state) { QTE_D(); - d->landmarkActor->SetVisibility(state); + if(d->landmarkOptions->isVisibleLandmarksChecked()) + { + d->visibleLandmarkActor->SetVisibility(state); + d->nonVisibleLandmarkActor->SetVisibility(state && !d->landmarkOptions-> + isVisibleLandmarksOnlyChecked()); + } + else + { + d->landmarkActor->SetVisibility(state); + } + d->updateAxes(this, true); } @@ -1041,6 +1250,19 @@ void WorldView::updateDepthMapThresholds() d->depthMapLoaded = true; } +//----------------------------------------------------------------------------- +void WorldView::switchToVisibleLandmarksMode(bool state) +{ + QTE_D(); + + d->landmarkActor->SetVisibility(!state); + d->visibleLandmarkActor->SetVisibility(state); + d->nonVisibleLandmarkActor->SetVisibility(state && !d->landmarkOptions-> + isVisibleLandmarksOnlyChecked()); + + d->UI.renderWidget->update(); +} + //----------------------------------------------------------------------------- void WorldView::exportWebGLScene(QString const& path) { diff --git a/gui/WorldView.h b/gui/WorldView.h index 3dfa63795..2d734f561 100644 --- a/gui/WorldView.h +++ b/gui/WorldView.h @@ -60,6 +60,8 @@ public slots: void addCamera(int id, vtkMaptkCamera* camera); void setLandmarks(kwiver::vital::landmark_map const&); + void setVisibleLandmarks(kwiver::vital::landmark_map const&); + void setNonVisibleLandmarks(kwiver::vital::landmark_map const&); void setActiveDepthMap(vtkMaptkCamera* camera, QString const& depthMapPath); void setImageData(vtkImageData* data, QSize const& dimensions); @@ -95,6 +97,8 @@ protected slots: void updateDepthMapDisplayMode(); void updateDepthMapThresholds(); + void switchToVisibleLandmarksMode(bool); + private: QTE_DECLARE_PRIVATE_RPTR(WorldView) QTE_DECLARE_PRIVATE(WorldView) diff --git a/gui/WorldView.ui b/gui/WorldView.ui index 63d50d779..f8b23b5e3 100644 --- a/gui/WorldView.ui +++ b/gui/WorldView.ui @@ -14,7 +14,16 @@ Form - + + 0 + + + 0 + + + 0 + + 0