From 9ecdc5eb43f3f9f4a5a0b91395855c7e7582b439 Mon Sep 17 00:00:00 2001 From: djairoh Date: Thu, 30 May 2024 18:14:27 +0200 Subject: [PATCH] feat: refactor spawnpointcallback --- particle-track-and-trace/src/CMakeLists.txt | 4 + .../src/QT/MainWindow.cpp | 2 +- .../src/QT/ui_mainwindow.h | 4 +- .../src/commands/MassSpawnPointCallback.cpp | 74 +++++++++++++++++++ .../src/commands/MassSpawnPointCallback.h | 30 ++++++++ .../commands/SingularSpawnPointCallback.cpp | 49 ++++++++++++ .../src/commands/SingularSpawnPointCallback.h | 18 +++++ .../src/commands/SpawnPointCallback.cpp | 49 ------------ .../src/commands/SpawnPointCallback.h | 46 +++++------- .../src/layers/LColLayer.cpp | 6 +- .../src/layers/LGlyphLayer.cpp | 5 +- particle-track-and-trace/src/main.cpp | 4 +- 12 files changed, 206 insertions(+), 85 deletions(-) create mode 100644 particle-track-and-trace/src/commands/MassSpawnPointCallback.cpp create mode 100644 particle-track-and-trace/src/commands/MassSpawnPointCallback.h create mode 100644 particle-track-and-trace/src/commands/SingularSpawnPointCallback.cpp create mode 100644 particle-track-and-trace/src/commands/SingularSpawnPointCallback.h diff --git a/particle-track-and-trace/src/CMakeLists.txt b/particle-track-and-trace/src/CMakeLists.txt index 2ae525f..ebfb6cc 100644 --- a/particle-track-and-trace/src/CMakeLists.txt +++ b/particle-track-and-trace/src/CMakeLists.txt @@ -71,6 +71,10 @@ add_executable(ParticleTrackTrace MACOSX_BUNDLE main.cpp commands/TimerCallbackCommand.cpp commands/SpawnPointCallback.h commands/SpawnPointCallback.cpp + commands/SingularSpawnPointCallback.h + commands/SingularSpawnPointCallback.cpp + commands/MassSpawnPointCallback.h + commands/MassSpawnPointCallback.cpp commands/CameraMoveCallback.cpp commands/CameraMoveCallback.h CartographicTransformation.cpp diff --git a/particle-track-and-trace/src/QT/MainWindow.cpp b/particle-track-and-trace/src/QT/MainWindow.cpp index fb0217a..ca50c02 100644 --- a/particle-track-and-trace/src/QT/MainWindow.cpp +++ b/particle-track-and-trace/src/QT/MainWindow.cpp @@ -61,7 +61,7 @@ void MainWindow::setupTechniques() { // add date/time layer auto tm = new TimeLayer(); technique1->addLayer(tm); - technique1->addLayer(tm); + technique2->addLayer(tm); // add Euler layers technique1->addLayer(new EColLayer(uvGrid)); diff --git a/particle-track-and-trace/src/QT/ui_mainwindow.h b/particle-track-and-trace/src/QT/ui_mainwindow.h index 0a3c634..f60fbd2 100644 --- a/particle-track-and-trace/src/QT/ui_mainwindow.h +++ b/particle-track-and-trace/src/QT/ui_mainwindow.h @@ -225,7 +225,6 @@ public: verticalLayout_16->addWidget(IregularlySubsampledButton); - verticalLayout_3->addWidget(ChannelBox); @@ -244,6 +243,9 @@ public: MainWindow->setCentralWidget(centralWidget); + // FIXME: remove this line to enable subsampling buttons + GlyphBox_2->hide(); + retranslateUi(MainWindow); QMetaObject::connectSlotsByName(MainWindow); diff --git a/particle-track-and-trace/src/commands/MassSpawnPointCallback.cpp b/particle-track-and-trace/src/commands/MassSpawnPointCallback.cpp new file mode 100644 index 0000000..3649277 --- /dev/null +++ b/particle-track-and-trace/src/commands/MassSpawnPointCallback.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include + +#include "MassSpawnPointCallback.h" +#include "../CartographicTransformation.h" + + +void MassSpawnPointCallback::Execute(vtkObject *caller, unsigned long evId, void *callData) { + // Note the use of reinterpret_cast to cast the caller to the expected type. + auto interactor = reinterpret_cast(caller); + + if (evId == vtkCommand::LeftButtonPressEvent) { + dragging = true; + } + if (evId == vtkCommand::LeftButtonReleaseEvent) { + dragging = false; + } + if (!dragging) { + return; + } + + int x, y; + interactor->GetEventPosition(x, y); + + randomParticles(x,y); + this->points->Modified(); + this->ren->GetRenderWindow()->Render(); +} + +void MassSpawnPointCallback::randomParticles(double x, double y) { + double worldPos[4] = {2, 0 ,0, 0}; + double displayPos[3] = {static_cast(x), static_cast(y), 0.0}; + this->ren->SetDisplayPoint(displayPos); + this->ren->DisplayToWorld(); + this->ren->GetWorldPoint(worldPos); + this->inverseCartographicProjection->TransformPoint(worldPos, worldPos); + + double mod[2] = {0,0}; + for (int i=0; i < 10; i++) { + mod[0] = this->lats[0] + static_cast (rand()) /( static_cast (RAND_MAX/(this->lats[1] - this->lats[0]))); + mod[1] = this->lons[0] + static_cast (rand()) /( static_cast (RAND_MAX/(this->lons[1] - this->lons[0]))); + addParticle(worldPos[0]+mod[0], worldPos[1]+mod[1]); + } +} + +void MassSpawnPointCallback::addParticle(double lon, double lat) { + points->InsertNextPoint(lon, lat, 0); + this->particlesBeached->InsertNextValue(0); + this->particlesAge->InsertNextValue(0); + this->lutIdx->InsertNextValue(0); +} + +MassSpawnPointCallback::MassSpawnPointCallback() {} + +MassSpawnPointCallback *MassSpawnPointCallback::New() { + return new MassSpawnPointCallback; +} + + + +void MassSpawnPointCallback::setUVGrid(const std::shared_ptr &uvGrid) { + this->uvGrid = uvGrid; + inverseCartographicProjection = createInverseCartographicTransformFilter(uvGrid)->GetTransform(); + + this->lats[0] = this->uvGrid->latStep()*-3; + this->lats[1] = this->uvGrid->latStep()*3; + this->lons[0] = this->uvGrid->lonStep()*-3; + this->lons[1] = this->uvGrid->lonStep()*3; + +} diff --git a/particle-track-and-trace/src/commands/MassSpawnPointCallback.h b/particle-track-and-trace/src/commands/MassSpawnPointCallback.h new file mode 100644 index 0000000..32fcf33 --- /dev/null +++ b/particle-track-and-trace/src/commands/MassSpawnPointCallback.h @@ -0,0 +1,30 @@ +#ifndef MASSSPAWNPOINTCALLBACK_H +#define MASSSPAWNPOINTCALLBACK_H +#include +#include +#include +#include +#include + +#include "SpawnPointCallback.h" + +class MassSpawnPointCallback : public SpawnPointCallback { + +public: + MassSpawnPointCallback(); + static MassSpawnPointCallback *New(); + + void setUVGrid(const std::shared_ptr &uvGrid) override; + +private: + double lats[2]; + double lons[2]; + + void randomParticles(double x, double y); + void addParticle(double x, double y); + void Execute(vtkObject *caller, unsigned long evId, void *callData) override; + +}; + + +#endif //SPAWNPOINTCALLBACK_H diff --git a/particle-track-and-trace/src/commands/SingularSpawnPointCallback.cpp b/particle-track-and-trace/src/commands/SingularSpawnPointCallback.cpp new file mode 100644 index 0000000..88b5be2 --- /dev/null +++ b/particle-track-and-trace/src/commands/SingularSpawnPointCallback.cpp @@ -0,0 +1,49 @@ +#include "SingularSpawnPointCallback.h" + +#include +#include +#include +#include +#include +#include + + +void SingularSpawnPointCallback::Execute(vtkObject *caller, unsigned long evId, void *callData) { + // Note the use of reinterpret_cast to cast the caller to the expected type. + auto interactor = reinterpret_cast(caller); + + if (evId == vtkCommand::LeftButtonPressEvent) { + dragging = true; + } + if (evId == vtkCommand::LeftButtonReleaseEvent) { + dragging = false; + } + if (!dragging) { + return; + } + + int x, y; + interactor->GetEventPosition(x, y); + + double worldPos[4] = {2, 0 ,0, 0}; + double displayPos[3] = {static_cast(x), static_cast(y), 0.0}; + this->ren->SetDisplayPoint(displayPos); + this->ren->DisplayToWorld(); + this->ren->GetWorldPoint(worldPos); + this->inverseCartographicProjection->TransformPoint(worldPos, worldPos); + + this->points->InsertNextPoint(worldPos[0], worldPos[1], 0); + this->particlesBeached->InsertNextValue(0); + this->particlesAge->InsertNextValue(0); + this->lutIdx->InsertNextValue(0); + + this->points->Modified(); + this->ren->GetRenderWindow()->Render(); +} + + +SingularSpawnPointCallback::SingularSpawnPointCallback() { } + +SingularSpawnPointCallback *SingularSpawnPointCallback::New() { + return new SingularSpawnPointCallback; +} diff --git a/particle-track-and-trace/src/commands/SingularSpawnPointCallback.h b/particle-track-and-trace/src/commands/SingularSpawnPointCallback.h new file mode 100644 index 0000000..4937fae --- /dev/null +++ b/particle-track-and-trace/src/commands/SingularSpawnPointCallback.h @@ -0,0 +1,18 @@ +#ifndef SINGULARSPAWNPOINTCALLBACK_H +#define SINGULARSPAWNPOINTCALLBACK_H + +#include "SpawnPointCallback.h" + +class SingularSpawnPointCallback : public SpawnPointCallback { + +public: + SingularSpawnPointCallback(); + static SingularSpawnPointCallback *New(); + +private: + void Execute(vtkObject *caller, unsigned long evId, void *callData) override; + +}; + + +#endif //SINGULARSPAWNPOINTCALLBACK_H diff --git a/particle-track-and-trace/src/commands/SpawnPointCallback.cpp b/particle-track-and-trace/src/commands/SpawnPointCallback.cpp index 92beb51..370ec94 100644 --- a/particle-track-and-trace/src/commands/SpawnPointCallback.cpp +++ b/particle-track-and-trace/src/commands/SpawnPointCallback.cpp @@ -1,58 +1,9 @@ #include "SpawnPointCallback.h" -#include -#include -#include #include -#include -#include #include "../CartographicTransformation.h" -void SpawnPointCallback::Execute(vtkObject *caller, unsigned long evId, void *callData) { - // Note the use of reinterpret_cast to cast the caller to the expected type. - auto interactor = reinterpret_cast(caller); - - if (evId == vtkCommand::LeftButtonPressEvent) { - dragging = true; - } - if (evId == vtkCommand::LeftButtonReleaseEvent) { - dragging = false; - } - if (!dragging) { - return; - } - - int x, y; - interactor->GetEventPosition(x, y); - - double worldPos[4] = {2, 0 ,0, 0}; - double displayPos[3] = {static_cast(x), static_cast(y), 0.0}; - ren->SetDisplayPoint(displayPos); - ren->DisplayToWorld(); - ren->GetWorldPoint(worldPos); - inverseCartographicProjection->TransformPoint(worldPos, worldPos); - - points->InsertNextPoint(worldPos[0], worldPos[1], 0); - this->particlesBeached->InsertNextValue(0); - this->particlesAge->InsertNextValue(0); - this->lutIdx->InsertNextValue(0); - - // FIXME: The below lines cause some weird interaction with our vtkTimer. - // see github issue https://github.com/MakeNEnjoy/interactive-track-and-trace/issues/28 - this->points->Modified(); - ren->GetRenderWindow()->Render(); -} - - -SpawnPointCallback::SpawnPointCallback() : points(nullptr), - inverseCartographicProjection(nullptr), - uvGrid(nullptr) { } - -SpawnPointCallback *SpawnPointCallback::New() { - return new SpawnPointCallback; -} - void SpawnPointCallback::setPoints(const vtkSmartPointer &points) { this->points = points; } diff --git a/particle-track-and-trace/src/commands/SpawnPointCallback.h b/particle-track-and-trace/src/commands/SpawnPointCallback.h index d33d41e..cdd6dda 100644 --- a/particle-track-and-trace/src/commands/SpawnPointCallback.h +++ b/particle-track-and-trace/src/commands/SpawnPointCallback.h @@ -2,33 +2,17 @@ #define SPAWNPOINTCALLBACK_H #include -#include -#include -#include -#include #include +#include +#include +#include +#include + #include "../advection/UVGrid.h" class SpawnPointCallback : public vtkCallbackCommand { - -public: - static SpawnPointCallback *New(); - - SpawnPointCallback(); - - void setPoints(const vtkSmartPointer &points); - - void setRen(const vtkSmartPointer &ren); - - void setBeached(const vtkSmartPointer &parts); - - void setAge(const vtkSmartPointer &parts); - void setIdx(const vtkSmartPointer &idx); - - void setUVGrid(const std::shared_ptr &uvGrid); - -private: +protected: vtkSmartPointer points; vtkSmartPointer ren; vtkSmartPointer particlesBeached; @@ -36,11 +20,19 @@ private: vtkSmartPointer lutIdx; std::shared_ptr uvGrid; vtkSmartPointer inverseCartographicProjection; - - void Execute(vtkObject *caller, unsigned long evId, void *callData) override; - bool dragging = false; + +public: + virtual void setPoints(const vtkSmartPointer &points); + + virtual void setRen(const vtkSmartPointer &ren); + + virtual void setBeached(const vtkSmartPointer &parts); + + virtual void setAge(const vtkSmartPointer &parts); + virtual void setIdx(const vtkSmartPointer &idx); + + virtual void setUVGrid(const std::shared_ptr &uvGrid); }; - -#endif //SPAWNPOINTCALLBACK_H +#endif diff --git a/particle-track-and-trace/src/layers/LColLayer.cpp b/particle-track-and-trace/src/layers/LColLayer.cpp index c2a151c..4bd2ddf 100644 --- a/particle-track-and-trace/src/layers/LColLayer.cpp +++ b/particle-track-and-trace/src/layers/LColLayer.cpp @@ -1,5 +1,3 @@ -#include "LColLayer.h" -#include "../commands/SpawnPointCallback.h" #include #include #include @@ -19,6 +17,8 @@ #include #include +#include "LColLayer.h" +#include "../commands/MassSpawnPointCallback.h" #include "../CartographicTransformation.h" #include "luts.h" @@ -28,7 +28,7 @@ using namespace std; // potential solution: spawn a number of particles randomly around the selected point instead. // Would involve a custom callback function probably. vtkSmartPointer LColLayer::createSpawnPointCallback() { - vtkNew newPointCallBack; + vtkNew newPointCallBack; newPointCallBack->setPoints(this->points); newPointCallBack->setRen(this->ren); newPointCallBack->setUVGrid(this->uvGrid); diff --git a/particle-track-and-trace/src/layers/LGlyphLayer.cpp b/particle-track-and-trace/src/layers/LGlyphLayer.cpp index 215efc4..6866e56 100644 --- a/particle-track-and-trace/src/layers/LGlyphLayer.cpp +++ b/particle-track-and-trace/src/layers/LGlyphLayer.cpp @@ -1,5 +1,5 @@ #include "LGlyphLayer.h" -#include "../commands/SpawnPointCallback.h" +#include "../commands/SingularSpawnPointCallback.h" #include #include #include @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,7 @@ #include "luts.h" vtkSmartPointer LGlyphLayer::createSpawnPointCallback() { - vtkNew newPointCallBack; + vtkNew newPointCallBack; newPointCallBack->setPoints(this->points); newPointCallBack->setRen(this->ren); newPointCallBack->setUVGrid(this->uvGrid); diff --git a/particle-track-and-trace/src/main.cpp b/particle-track-and-trace/src/main.cpp index c958410..1a5ab06 100644 --- a/particle-track-and-trace/src/main.cpp +++ b/particle-track-and-trace/src/main.cpp @@ -2,9 +2,7 @@ #include #include "QT/MainWindow.h" -// TODO: make LColLayer use a modified spawnpointCallback to spawn multiple particles per interaction // TODO: make Lagrangian Layers share one vtkPoints for seemless technique swiching -// TODO: add text gui explaining the above? // TODO: yoink Robin's isNearestNeighbourZero function to improve beaching // TODO: add a button to reset the simulation - set time=0 and reset points array of particles. // FIXME: go over each function and add const where appropriate. @@ -13,6 +11,8 @@ // COULDHAVE: the Legends are just statically rendered images; ideally these would be created along with the luts and then displayed accordingly. int main(int argc, char* argv[]) { + srand (static_cast (time(0))); + QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat()); QApplication app(argc, argv);