From e53a934212f0065a608fd488cf48c4851b0b725c Mon Sep 17 00:00:00 2001 From: djairoh Date: Thu, 23 May 2024 22:45:11 +0200 Subject: [PATCH 1/8] added new option to modulate brightness for LGlyphLayer --- .../src/layers/LColLayer.cpp | 0 .../src/layers/LColLayer.h | 0 .../src/layers/LGlyphLayer.cpp | 55 ++++++++++++++++--- .../src/layers/LGlyphLayer.h | 6 ++ particle-track-and-trace/src/main.cpp | 3 +- particle-track-and-trace/src/technique.cpp | 0 particle-track-and-trace/src/technique.h | 25 +++++++++ 7 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 particle-track-and-trace/src/layers/LColLayer.cpp create mode 100644 particle-track-and-trace/src/layers/LColLayer.h create mode 100644 particle-track-and-trace/src/technique.cpp create mode 100644 particle-track-and-trace/src/technique.h diff --git a/particle-track-and-trace/src/layers/LColLayer.cpp b/particle-track-and-trace/src/layers/LColLayer.cpp new file mode 100644 index 0000000..e69de29 diff --git a/particle-track-and-trace/src/layers/LColLayer.h b/particle-track-and-trace/src/layers/LColLayer.h new file mode 100644 index 0000000..e69de29 diff --git a/particle-track-and-trace/src/layers/LGlyphLayer.cpp b/particle-track-and-trace/src/layers/LGlyphLayer.cpp index 5dbd57b..311a2f7 100644 --- a/particle-track-and-trace/src/layers/LGlyphLayer.cpp +++ b/particle-track-and-trace/src/layers/LGlyphLayer.cpp @@ -33,12 +33,36 @@ vtkSmartPointer LGlyphLayer::createSpawnPointCallback() { // Further notes; current thinking is to allow tracking a particle's age by using a scalar array in the VtkPolyData. This would be incremented for every tick/updateData function call. +/** + * Build and returns a vtkLookupTable for the given number of colours in grayscale. + * @param n : number of colours to add to the SetTableRange + * @return : a vtkLookupTable with grayscale colours from [1,1,1,1] to [0.25, 0.25, 0.25, 1] in n steps. + */ +vtkSmartPointer buildLutBrightness(int n) { + vtkNew lut; + lut->SetNumberOfColors(n); + lut->SetTableRange(0, n); + lut->SetScaleToLinear(); + lut->Build(); + for (int i=0; i < n; i++) { + lut->SetTableValue(i, 1-(0.75*i/(n-1)), 1-(0.75*i/(n-1)), 1-(0.75*i/(n-1)), 1); + } + lut->UseAboveRangeColorOn(); + lut->SetAboveRangeColor(0.2, 0.2, 0.2, 1); + + // We cheat a little here: any particle with an age of -1 is out of bounds, and thus set invisible. + lut->UseBelowRangeColorOn(); + lut->SetBelowRangeColor(1,1,1,0); + + return lut; +} + /** * Build and returns a vtkLookupTable for the given number of colours in grayscale. * @param n : number of colours to add to the SetTableRange * @return : a vtkLookupTable with grayscale colours from [1,1,1,1] to [1,1,1,0.25] in n steps. */ -vtkSmartPointer buildLut(int n) { +vtkSmartPointer buildLutOpacity(int n) { vtkNew lut; lut->SetNumberOfColors(n); lut->SetTableRange(0, n); @@ -58,6 +82,9 @@ vtkSmartPointer buildLut(int n) { } LGlyphLayer::LGlyphLayer(std::shared_ptr uvGrid, std::unique_ptr advectionKernel) { + this->luts.push(buildLutOpacity(512)); + this->luts.push(buildLutBrightness(512)); + this->ren = vtkSmartPointer::New(); this->ren->SetLayer(2); @@ -94,15 +121,20 @@ LGlyphLayer::LGlyphLayer(std::shared_ptr uvGrid, std::unique_ptrSetScaleModeToDataScalingOff(); glyph2D->Update(); - vtkNew mapper; - mapper->SetInputConnection(glyph2D->GetOutputPort()); - mapper->SetColorModeToMapScalars(); - mapper->SetLookupTable(buildLut(512)); - mapper->UseLookupTableScalarRangeOn(); - mapper->Update(); + this->mapper = vtkSmartPointer::New(); + this->mapper->SetInputConnection(glyph2D->GetOutputPort()); + this->mapper->SetColorModeToMapScalars(); + + auto lut = this->luts.front(); + mapper->SetLookupTable(lut); + this->luts.pop(); + this->luts.push(lut); + + this->mapper->UseLookupTableScalarRangeOn(); + this->mapper->Update(); vtkNew actor; - actor->SetMapper(mapper); + actor->SetMapper(this->mapper); this->ren->AddActor(actor); } @@ -174,6 +206,13 @@ void LGlyphLayer::addObservers(vtkSmartPointer intera } +void LGlyphLayer::cycleGlyphStyle() { + auto lut = this->luts.front(); + this->mapper->SetLookupTable(lut); + this->luts.pop(); + this->luts.push(lut); +} + void LGlyphLayer::setDt(int dt) { this->dt = dt; } diff --git a/particle-track-and-trace/src/layers/LGlyphLayer.h b/particle-track-and-trace/src/layers/LGlyphLayer.h index 8cec151..e15d0f1 100644 --- a/particle-track-and-trace/src/layers/LGlyphLayer.h +++ b/particle-track-and-trace/src/layers/LGlyphLayer.h @@ -4,6 +4,7 @@ #include "Layer.h" #include "../advection/kernel/AdvectionKernel.h" #include "../commands/SpawnPointCallback.h" +#include #include #include @@ -16,10 +17,12 @@ private: vtkSmartPointer data; vtkSmartPointer particlesBeached; vtkSmartPointer particlesAge; + vtkSmartPointer mapper; std::unique_ptr advector; std::shared_ptr uvGrid; int dt = 3600; int beachedAtNumberOfTimes = 20; + std::queue> luts; public: /** Constructor. @@ -41,6 +44,9 @@ public: void addObservers(vtkSmartPointer interactor) override; + /** This function cycles which lut is used for the layer, according to the lookuptables in the luts attribute. + */ + void cycleGlyphStyle(); /** * Sets a custom DT value, needed for advect calls to the simulation logic. diff --git a/particle-track-and-trace/src/main.cpp b/particle-track-and-trace/src/main.cpp index 6997c65..aa69646 100644 --- a/particle-track-and-trace/src/main.cpp +++ b/particle-track-and-trace/src/main.cpp @@ -33,9 +33,10 @@ int main() { auto l = new LGlyphLayer(uvGrid, std::move(kernelRK4BoundaryChecked)); l->spoofPoints(); l->setDt(DT); + l->cycleGlyphStyle(); unique_ptr program = make_unique(DT); - program->addLayer(new BackgroundImage(dataPath + "/map_661-661.png")); + program->addLayer(new BackgroundImage(dataPath + "/map_qgis.png")); // program->addLayer(new EGlyphLayer(uvGrid)); program->addLayer(new EColLayer(uvGrid)); program->addLayer(l); diff --git a/particle-track-and-trace/src/technique.cpp b/particle-track-and-trace/src/technique.cpp new file mode 100644 index 0000000..e69de29 diff --git a/particle-track-and-trace/src/technique.h b/particle-track-and-trace/src/technique.h new file mode 100644 index 0000000..e43888a --- /dev/null +++ b/particle-track-and-trace/src/technique.h @@ -0,0 +1,25 @@ +#ifndef TECHNIQUE_H +#define TECHNIQUE_H + +#include "layers/Layer.h" +#include +class Technique { +private: + std::vector layers; + vtkSmartPointer points; + vtkSmartPointer data; + + void setupInteractions(); + +public: + Technique(); + void addLayer(Layer *l); + void removeLayer(Layer *l); + void updateData(int t); + int numberOfLayers(); + +}; + + + +#endif From e54501e9e16797e1ca94f164770c0cc11171f2fc Mon Sep 17 00:00:00 2001 From: djairoh Date: Thu, 23 May 2024 23:14:01 +0200 Subject: [PATCH 2/8] fix: bg map resolution --- particle-track-and-trace/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/particle-track-and-trace/src/main.cpp b/particle-track-and-trace/src/main.cpp index aa69646..a677041 100644 --- a/particle-track-and-trace/src/main.cpp +++ b/particle-track-and-trace/src/main.cpp @@ -33,10 +33,11 @@ int main() { auto l = new LGlyphLayer(uvGrid, std::move(kernelRK4BoundaryChecked)); l->spoofPoints(); l->setDt(DT); + // TODO: implement feature to call this function on widget l->cycleGlyphStyle(); unique_ptr program = make_unique(DT); - program->addLayer(new BackgroundImage(dataPath + "/map_qgis.png")); + program->addLayer(new BackgroundImage(dataPath + "/map_qgis_1035.png")); // program->addLayer(new EGlyphLayer(uvGrid)); program->addLayer(new EColLayer(uvGrid)); program->addLayer(l); From 56dde02af8264654179445822e2cd3a3fdcc944d Mon Sep 17 00:00:00 2001 From: djairoh Date: Fri, 24 May 2024 02:58:55 +0200 Subject: [PATCH 3/8] feat: EColLayer according to flow direction --- particle-track-and-trace/src/CMakeLists.txt | 2 - .../src/layers/EColLayer.cpp | 67 ++++++++++++++++--- .../src/layers/EColLayer.h | 1 + particle-track-and-trace/src/main.cpp | 2 +- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/particle-track-and-trace/src/CMakeLists.txt b/particle-track-and-trace/src/CMakeLists.txt index cf6696a..dabecca 100644 --- a/particle-track-and-trace/src/CMakeLists.txt +++ b/particle-track-and-trace/src/CMakeLists.txt @@ -48,8 +48,6 @@ add_executable(ParticleTrackTrace MACOSX_BUNDLE main.cpp layers/Layer.h layers/LGlyphLayer.cpp layers/LGlyphLayer.h - layers/LColLayer.cpp - layers/LColLayer.h Program.cpp Program.h commands/TimerCallbackCommand.h diff --git a/particle-track-and-trace/src/layers/EColLayer.cpp b/particle-track-and-trace/src/layers/EColLayer.cpp index e6c5325..c7df049 100644 --- a/particle-track-and-trace/src/layers/EColLayer.cpp +++ b/particle-track-and-trace/src/layers/EColLayer.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -24,8 +25,9 @@ #include "../CartographicTransformation.h" -using namespace std; +using std::numbers::pi; +using namespace std; EColLayer::EColLayer(std::shared_ptr uvGrid) { this->ren = vtkSmartPointer::New(); @@ -41,9 +43,53 @@ EColLayer::EColLayer(std::shared_ptr uvGrid) { this->strength->SetNumberOfComponents(1); this->strength->SetNumberOfTuples((numLats-1)*(numLons-1)); + this->direction = vtkSmartPointer::New(); + this->direction->SetName("direction"); + this->direction->SetNumberOfComponents(1); + this->direction->SetNumberOfTuples((numLats-1)*(numLons-1)); + readCoordinates(); } +/** + * Sets a given rgba colour to a range of values [start, end] in the lut. + * @param lut : lookuptable to operate on. + * @ param start : starting index of range to assign + * @ param end: ending index of range to assign + * @param r : red value [0,1] + * @param g : green value [0,1] + * @param n : blue value [0,1] + * @param a : alpha value [0,1] + */ +void setLutRange(vtkSmartPointer lut, int start, int end, double r, double g, double b, double a) { + for (int i=start; i <= end; i++) { + lut->SetTableValue(i, r, g, b, a); + } +} + +// builds a 4-way lookuptable, used to encode the directional component +vtkSmartPointer buildLutDirs() { + vtkNew lut; + lut->SetNumberOfColors(360); + lut->SetTableRange(0, 359); + lut->SetScaleToLinear(); + lut->Build(); + //currently builds a corkO cyclic colour map, divided into 8 colours (see https://www.fabiocrameri.ch/cycliccolourmaps/) + setLutRange(lut, 000, 020, 0.247, 0.243, 0.227, 1); + setLutRange(lut, 021, 060, 0.243, 0.267, 0.365, 1); + setLutRange(lut, 061, 100, 0.318, 0.416, 0.557, 1); + setLutRange(lut, 101, 140, 0.518, 0.620, 0.729, 1); + setLutRange(lut, 141, 180, 0.667, 0.757, 0.773, 1); + setLutRange(lut, 181, 220, 0.631, 0.769, 0.651, 1); + setLutRange(lut, 221, 260, 0.451, 0.639, 0.435, 1); + setLutRange(lut, 261, 300, 0.298, 0.431, 0.224, 1); + setLutRange(lut, 301, 340, 0.263, 0.310, 0.173, 1); + setLutRange(lut, 341, 359, 0.247, 0.243, 0.227, 1); + + lut->SetNanColor(0,0,0,0); + + return lut; +} // TODO: Bit of a superfunction here; can do with some refactoring. void EColLayer::readCoordinates() { @@ -64,27 +110,26 @@ void EColLayer::readCoordinates() { for (auto lat : uvGrid->lats) { double out[3] = {lon, lat, 0}; transform->TransformPoint(out, out); - // cout << "inserting point (" << pointId << "): " << out[0] << " " << out[1] << endl; points->InsertPoint(pointId++, out[0], out[1], 0); + // logic for adding cells if (latIndex > 0 and lonIndex > 0 ) { int idx = latIndex+lonIndex*numLats; - // cout << idx << " at " << lonIndex << " " << latIndex << endl; vtkNew l; l->SetNumberOfIds(4); l->SetId(0, idx-1); l->SetId(1, idx-numLats-1); l->SetId(2, idx-numLats); l->SetId(3, idx); - // cout << "inserting cell: " << idx-1 << " " << idx-numLats-1 << " " << idx- numLats<< " " << idx << endl; + double coords[12]; points->GetPoint(idx-1, coords); points->GetPoint(idx-numLats-1, coords+3); points->GetPoint(idx-numLats, coords+6); points->GetPoint(idx, coords+9); - // cout << "Inserting cell with points at: (" << coords[0] << " " << coords[1] << "), (" << coords[3] << " " << coords[4] << "), (" << coords[6] << " " << coords[7] << "), (" << coords[9] << " " << coords[10] << ")" << endl; data->InsertNextCell(VTK_QUAD, l); + // ltake the average of the four surrounding points as the cell's velocity. double u=0, v=0; for (int j=0; j < 2; j++ ) { for (int k=0; k < 2; k++ ) { @@ -95,7 +140,8 @@ void EColLayer::readCoordinates() { } u /= 4; v /= 4; - this->strength->SetTuple1(cellId++, std::sqrt(u*u + v*v)); + this->strength->SetTuple1(cellId, std::sqrt(u*u + v*v)); + this->direction->SetTuple1(cellId++, atan(u/v)*180/pi); } latIndex++; } @@ -103,11 +149,15 @@ void EColLayer::readCoordinates() { } data->GetCellData()->AddArray(this->strength); - data->GetCellData()->SetActiveScalars("strength"); + data->GetCellData()->AddArray(this->direction); + // data->GetCellData()->SetActiveScalars("strength"); vtkNew(mapper); mapper->SetInputData(data); + mapper->SetLookupTable(buildLutDirs()); + mapper->UseLookupTableScalarRangeOn(); mapper->Update(); + data->GetCellData()->SetActiveScalars("direction"); vtkNew actor; actor->SetMapper(mapper); @@ -137,7 +187,8 @@ void EColLayer::updateData(int t) { } u /= 4; v /= 4; - this->strength->SetTuple1(i++, std::sqrt(u*u + v*v)); + this->strength->SetTuple1(i, std::sqrt(u*u + v*v)); + this->direction->SetTuple1(i++, atan(u/v)*180/pi); } } this->strength->Modified(); diff --git a/particle-track-and-trace/src/layers/EColLayer.h b/particle-track-and-trace/src/layers/EColLayer.h index 4934728..1097d21 100644 --- a/particle-track-and-trace/src/layers/EColLayer.h +++ b/particle-track-and-trace/src/layers/EColLayer.h @@ -15,6 +15,7 @@ class EColLayer : public Layer { private: vtkSmartPointer strength; + vtkSmartPointer direction; std::shared_ptr uvGrid; int numLats; int numLons; diff --git a/particle-track-and-trace/src/main.cpp b/particle-track-and-trace/src/main.cpp index 00cc38d..7d768d5 100644 --- a/particle-track-and-trace/src/main.cpp +++ b/particle-track-and-trace/src/main.cpp @@ -35,7 +35,7 @@ int main() { l->setDt(DT); unique_ptr program = make_unique(DT); - program->addLayer(new BackgroundImage(dataPath + "/map_661-661.png")); + program->addLayer(new BackgroundImage(dataPath + "/map_qgis_1035.png")); // program->addLayer(new EGlyphLayer(uvGrid)); program->addLayer(new EColLayer(uvGrid)); program->addLayer(l); From c80d258c453c9be08a2dd2643252dba23faa2238 Mon Sep 17 00:00:00 2001 From: djairoh Date: Fri, 24 May 2024 17:07:13 +0200 Subject: [PATCH 4/8] fix: tweaked ecolLayer opacity --- particle-track-and-trace/src/layers/EColLayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/particle-track-and-trace/src/layers/EColLayer.cpp b/particle-track-and-trace/src/layers/EColLayer.cpp index c7df049..ebd59bf 100644 --- a/particle-track-and-trace/src/layers/EColLayer.cpp +++ b/particle-track-and-trace/src/layers/EColLayer.cpp @@ -162,7 +162,7 @@ void EColLayer::readCoordinates() { vtkNew actor; actor->SetMapper(mapper); actor->GetProperty()->SetColor(0, 1, 0); - actor->GetProperty()->SetOpacity(0.2); + actor->GetProperty()->SetOpacity(0.5); // vtkNew act2; // act2->SetMapper(mapper); From 4a5b7c4712aa2a510724ae725db68b2830ae9903 Mon Sep 17 00:00:00 2001 From: djairoh Date: Sat, 25 May 2024 14:35:54 +0200 Subject: [PATCH 5/8] working ver with QT --- particle-track-and-trace/src/CMakeLists.txt | 10 +- particle-track-and-trace/src/Program.cpp | 17 +- particle-track-and-trace/src/Program.h | 15 +- .../src/QT/MainWindow.cpp | 57 +++++ particle-track-and-trace/src/QT/MainWindow.h | 35 +++ particle-track-and-trace/src/QT/MainWindow.ui | 210 ++++++++++++++++++ particle-track-and-trace/src/main.cpp | 73 +++++- 7 files changed, 397 insertions(+), 20 deletions(-) create mode 100644 particle-track-and-trace/src/QT/MainWindow.cpp create mode 100644 particle-track-and-trace/src/QT/MainWindow.h create mode 100644 particle-track-and-trace/src/QT/MainWindow.ui diff --git a/particle-track-and-trace/src/CMakeLists.txt b/particle-track-and-trace/src/CMakeLists.txt index dabecca..1494578 100644 --- a/particle-track-and-trace/src/CMakeLists.txt +++ b/particle-track-and-trace/src/CMakeLists.txt @@ -7,6 +7,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +find_package(Qt5Core REQUIRED) +find_package(Qt5Gui REQUIRED) +find_package(Qt5Widgets REQUIRED) +find_package(Qt5OpenGL REQUIRED) + find_package(VTK COMPONENTS GeovisCore CommonColor @@ -72,6 +77,9 @@ add_executable(ParticleTrackTrace MACOSX_BUNDLE main.cpp advection/Vel.h advection/kernel/SnapBoundaryConditionKernel.h advection/kernel/SnapBoundaryConditionKernel.cpp + # QT/MainWindow.h + # QT/MainWindow.cpp + # QT/MainWindow.ui ) execute_process( @@ -92,7 +100,7 @@ find_library(NETCDF_LIB NAMES netcdf-cxx4 netcdf_c++4 PATHS ${NETCDFCXX_LIB_DIR} # Prevent a "command line is too long" failure in Windows. set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.") -target_link_libraries(ParticleTrackTrace ${NETCDF_LIB} ${VTK_LIBRARIES}) +target_link_libraries(ParticleTrackTrace ${NETCDF_LIB} ${VTK_LIBRARIES} Qt5::Widgets Qt5::OpenGL VTK::GUISupportQt VTK::IOLegacy) # vtk_module_autoinit is needed vtk_module_autoinit( diff --git a/particle-track-and-trace/src/Program.cpp b/particle-track-and-trace/src/Program.cpp index bae7b2c..f36da4d 100644 --- a/particle-track-and-trace/src/Program.cpp +++ b/particle-track-and-trace/src/Program.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -27,11 +28,11 @@ void Program::setWinProperties() { this->win->SetSize(661, 661); this->win->SetDesiredUpdateRate(60); - this->interact->SetRenderWindow(this->win); + this->interact->SetRenderWindow(this->win.Get()); this->interact->Initialize(); vtkNew style; - interact->SetInteractorStyle(style); + this->interact->SetInteractorStyle(style); } void Program::setupTimer(int dt) { @@ -50,10 +51,12 @@ void Program::setupCameraCallback() { this->interact->AddObserver(vtkCommand::KeyPressEvent, callback); } - -Program::Program(int timerDT) { - this->win = vtkSmartPointer::New(); - this->interact = vtkSmartPointer::New(); +Program::Program(int timerDT, vtkSmartPointer win) { + // this->win = vtkSmartPointer::New(); + this->win = win; + // this->interact = vtkSmartPointer::New(); + // this->interact = vtkSmartPointer::New(); + this->interact = win->GetInteractor(); this->cam = createNormalisedCamera(); this->win->SetNumberOfLayers(0); @@ -91,7 +94,7 @@ void Program::updateData(int t) { void Program::setupInteractions() { for (Layer *l: layers) { - l->addObservers(interact); + l->addObservers(this->interact); } } diff --git a/particle-track-and-trace/src/Program.h b/particle-track-and-trace/src/Program.h index 5009957..e591a04 100644 --- a/particle-track-and-trace/src/Program.h +++ b/particle-track-and-trace/src/Program.h @@ -1,6 +1,7 @@ #ifndef PROGRAM_H #define PROGRAM_H +#include #include #include #include @@ -18,11 +19,13 @@ private: /** The window this program's layers render to. */ - vtkSmartPointer win; + // vtkSmartPointer win; + vtkSmartPointer win; /** The interactor through which the layers can interact with the window. */ vtkSmartPointer interact; + // vtkSmartPointer interact; /** The camera used by all layers for this program. @@ -37,9 +40,6 @@ private: */ void setupTimer(int dt); - /** This function adds all interactors of each layer to the interactor/window - */ - void setupInteractions(); /** This function sets up the camera's associated movement callbacks.. */ @@ -48,7 +48,7 @@ private: public: /** Constructor. */ - Program(int timerDT); + Program(int timerDT, vtkSmartPointer win); /** This function adds a new layer (and thus vtkRenderer) to the program. * The layer is expected to set its own position in the vtkRenderWindow layer system. @@ -68,11 +68,16 @@ public: */ void updateData(int t); + /** This function adds all interactors of each layer to the interactor/window + */ + void setupInteractions(); + /** * This function renders the vtkRenderWindow for the first time. * Only call this function once! */ void render(); + }; #endif diff --git a/particle-track-and-trace/src/QT/MainWindow.cpp b/particle-track-and-trace/src/QT/MainWindow.cpp new file mode 100644 index 0000000..486fbbf --- /dev/null +++ b/particle-track-and-trace/src/QT/MainWindow.cpp @@ -0,0 +1,57 @@ +#include "MainWindow.h" + +#include +#include +#include + +#include + +MainWindow::MainWindow(QWidget* parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); +} + +MainWindow::~MainWindow() { delete ui; } + +void MainWindow::showAboutDialog() +{ + QMessageBox::information( + this, "About", + "interactive particle in-fluid simulation program for surface level advection."); +} + +void MainWindow::showOpenFileDialog() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Open file"), "", + "VTK Files (*.vtk)"); + + // Open file + QFile file(fileName); + file.open(QIODevice::ReadOnly); + + // Return on Cancel + if (!file.exists()) + return; + + openFile(fileName); +} + +void MainWindow::openFile(const QString& fileName) +{ + ui->sceneWidget->removeDataSet(); + + // Create reader + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(fileName.toStdString().c_str()); + + // Read the file + reader->Update(); + + // Add data set to 3D view + vtkSmartPointer dataSet = reader->GetOutput(); + if (dataSet != nullptr) { + ui->sceneWidget->addDataSet(reader->GetOutput()); + } +} diff --git a/particle-track-and-trace/src/QT/MainWindow.h b/particle-track-and-trace/src/QT/MainWindow.h new file mode 100644 index 0000000..679c0dc --- /dev/null +++ b/particle-track-and-trace/src/QT/MainWindow.h @@ -0,0 +1,35 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow { + Q_OBJECT + +public: + explicit MainWindow(QWidget* parent = 0); + ~MainWindow(); + +public slots: + //! Show the 'About this application' dialog + void showAboutDialog(); + + //! Show the 'Open file...' dialog + void showOpenFileDialog(); + +protected: + //! Open a file + /*! + \param[in] fileName The name of the file including the path + */ + void openFile(const QString& fileName); + +private: + Ui::MainWindow* ui; +}; + +#endif diff --git a/particle-track-and-trace/src/QT/MainWindow.ui b/particle-track-and-trace/src/QT/MainWindow.ui new file mode 100644 index 0000000..6865dec --- /dev/null +++ b/particle-track-and-trace/src/QT/MainWindow.ui @@ -0,0 +1,210 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + Qt VTK Viewer + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + 0 + 800 + 21 + + + + + File + + + + + + + + Help + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + :/icons/open_file.png:/icons/open_file.png + + + Open file... + + + Open file... + + + Ctrl+O + + + + + + :/icons/zoom_to.png:/icons/zoom_to.png + + + Zoom to extent + + + Zoom to extent + + + + + + :/icons/quit.png:/icons/quit.png + + + Quit + + + Ctrl+Q + + + + + + :/icons/about.png:/icons/about.png + + + About + + + + + + SceneWidget + QOpenGLWidget +
scenewidget.h
+ + zoomToExtent() + +
+
+ + + + + + actionOpenFile + triggered() + MainWindow + showOpenFileDialog() + + + -1 + -1 + + + 399 + 299 + + + + + actionQuit + triggered() + MainWindow + close() + + + -1 + -1 + + + 399 + 299 + + + + + actionZoomToExtent + triggered() + sceneWidget + zoomToExtent() + + + -1 + -1 + + + 399 + 314 + + + + + actionAbout + triggered() + MainWindow + showAboutDialog() + + + -1 + -1 + + + 399 + 299 + + + + + + showOpenFileDialog() + showAboutDialog() + +
diff --git a/particle-track-and-trace/src/main.cpp b/particle-track-and-trace/src/main.cpp index a677041..b49b4f0 100644 --- a/particle-track-and-trace/src/main.cpp +++ b/particle-track-and-trace/src/main.cpp @@ -18,11 +18,58 @@ #include "advection/kernel/RK4AdvectionKernel.h" #include "advection/kernel/SnapBoundaryConditionKernel.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "QT/MainWindow.h" + using namespace std; #define DT 60 * 60 // 60 sec/min * 60 mins -int main() { +int main(int argc, char* argv[]) { + QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat()); + + QApplication app(argc, argv); + + // Main window. + QMainWindow mainWindow; + mainWindow.resize(1200, 900); + + // Control area. + QDockWidget controlDock; + mainWindow.addDockWidget(Qt::LeftDockWidgetArea, &controlDock); + + QLabel controlDockTitle("Control Dock"); + controlDockTitle.setMargin(20); + controlDock.setTitleBarWidget(&controlDockTitle); + + QPointer dockLayout = new QVBoxLayout(); + QWidget layoutContainer; + layoutContainer.setLayout(dockLayout); + controlDock.setWidget(&layoutContainer); + + QPushButton randomizeButton; + randomizeButton.setText("Randomize"); + dockLayout->addWidget(&randomizeButton); + + // Render area. + QPointer vtkRenderWidget = + new QVTKOpenGLNativeWidget(); + mainWindow.setCentralWidget(vtkRenderWidget); + + // VTK part. + vtkNew window; + vtkRenderWidget->setRenderWindow(window.Get()); + + cout << "Reading data..." << endl; string dataPath = "../../../../data"; shared_ptr uvGrid = make_shared(dataPath); @@ -31,19 +78,31 @@ int main() { cout << "Starting vtk..." << endl; auto l = new LGlyphLayer(uvGrid, std::move(kernelRK4BoundaryChecked)); - l->spoofPoints(); + // l->spoofPoints(); l->setDt(DT); // TODO: implement feature to call this function on widget - l->cycleGlyphStyle(); + // l->cycleGlyphStyle(); - unique_ptr program = make_unique(DT); + unique_ptr program = make_unique(DT, window); program->addLayer(new BackgroundImage(dataPath + "/map_qgis_1035.png")); - // program->addLayer(new EGlyphLayer(uvGrid)); + // TODO: implement feature to cycle between layers thru QT + program->addLayer(new EGlyphLayer(uvGrid)); program->addLayer(new EColLayer(uvGrid)); program->addLayer(l); - program->render(); + program->setupInteractions(); - return EXIT_SUCCESS; + // program->render(); + + // Setup initial status. + // std::mt19937 randEng(0); + // ::Randomize(sphere, mapper, window, randEng); + + // connect the buttons + // QObject::connect(&randomizeButton, &QPushButton::released, + // [&]() { ::Randomize(sphere, mapper, window, randEng); }); + + mainWindow.show(); + return app.exec(); } From 7d7e1a5b95b581dd0ac552a6257b40f379f0bddd Mon Sep 17 00:00:00 2001 From: djairoh Date: Sun, 26 May 2024 03:03:21 +0200 Subject: [PATCH 6/8] feat: qwidget layout --- particle-track-and-trace/src/CMakeLists.txt | 8 +- particle-track-and-trace/src/Program.cpp | 12 +- particle-track-and-trace/src/Program.h | 7 +- .../src/QT/MainWindow.cpp | 159 ++++-- particle-track-and-trace/src/QT/MainWindow.h | 28 +- particle-track-and-trace/src/QT/MainWindow.ui | 525 +++++++++++------- .../src/QT/ui_mainwindow.h | 282 ++++++++++ particle-track-and-trace/src/main.cpp | 48 +- 8 files changed, 801 insertions(+), 268 deletions(-) create mode 100644 particle-track-and-trace/src/QT/ui_mainwindow.h diff --git a/particle-track-and-trace/src/CMakeLists.txt b/particle-track-and-trace/src/CMakeLists.txt index 1494578..ff62643 100644 --- a/particle-track-and-trace/src/CMakeLists.txt +++ b/particle-track-and-trace/src/CMakeLists.txt @@ -5,6 +5,7 @@ project(ParticleTrackTrace) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_AUTOMOC ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) find_package(Qt5Core REQUIRED) @@ -77,9 +78,10 @@ add_executable(ParticleTrackTrace MACOSX_BUNDLE main.cpp advection/Vel.h advection/kernel/SnapBoundaryConditionKernel.h advection/kernel/SnapBoundaryConditionKernel.cpp - # QT/MainWindow.h - # QT/MainWindow.cpp - # QT/MainWindow.ui + QT/MainWindow.h + QT/MainWindow.cpp + QT/MainWindow.ui + QT/ui_mainwindow.h ) execute_process( diff --git a/particle-track-and-trace/src/Program.cpp b/particle-track-and-trace/src/Program.cpp index f36da4d..c75b93e 100644 --- a/particle-track-and-trace/src/Program.cpp +++ b/particle-track-and-trace/src/Program.cpp @@ -51,17 +51,17 @@ void Program::setupCameraCallback() { this->interact->AddObserver(vtkCommand::KeyPressEvent, callback); } -Program::Program(int timerDT, vtkSmartPointer win) { - // this->win = vtkSmartPointer::New(); - this->win = win; +Program::Program(QWidget *parent): QVTKOpenGLNativeWidget(parent) { + this->win = vtkSmartPointer::New(); // this->interact = vtkSmartPointer::New(); // this->interact = vtkSmartPointer::New(); + setRenderWindow(this->win); this->interact = win->GetInteractor(); this->cam = createNormalisedCamera(); this->win->SetNumberOfLayers(0); setWinProperties(); - setupTimer(timerDT); + setupTimer(60 * 60); // FIXME: manually tracking this variable is a little stupid. setupCameraCallback(); } @@ -103,3 +103,7 @@ void Program::render() { win->Render(); interact->Start(); } + +Program::~Program() { + cout << "deleting program" << endl; +} diff --git a/particle-track-and-trace/src/Program.h b/particle-track-and-trace/src/Program.h index e591a04..60fc6e3 100644 --- a/particle-track-and-trace/src/Program.h +++ b/particle-track-and-trace/src/Program.h @@ -11,7 +11,9 @@ /** This class manages the upper levels of the vtk pipeline; it has attributes for the vtkrenderWindow and a vector of Layers to represent a variable number of vtkRenderers. * It can also set up a vtkTimer by connecting an instance of TimerCallbackCommand with its contained vtkRenderWindowInteractor. */ -class Program { +class Program : public QVTKOpenGLNativeWidget { + Q_OBJECT + private: /** This attribute models a variable number of vtkRenderers, managed through the abstract Layer class. */ @@ -48,7 +50,8 @@ private: public: /** Constructor. */ - Program(int timerDT, vtkSmartPointer win); + Program(QWidget *parent = nullptr); + ~Program() override; /** This function adds a new layer (and thus vtkRenderer) to the program. * The layer is expected to set its own position in the vtkRenderWindow layer system. diff --git a/particle-track-and-trace/src/QT/MainWindow.cpp b/particle-track-and-trace/src/QT/MainWindow.cpp index 486fbbf..09245d8 100644 --- a/particle-track-and-trace/src/QT/MainWindow.cpp +++ b/particle-track-and-trace/src/QT/MainWindow.cpp @@ -1,4 +1,5 @@ #include "MainWindow.h" +#include "ui_mainwindow.h" #include #include @@ -6,52 +7,144 @@ #include +#include "../layers/BackgroundImage.h" +#include "../layers/EColLayer.h" +#include "../layers/EGlyphLayer.h" +#include "../layers/LGlyphLayer.h" +#include "../Program.h" +#include "../advection/UVGrid.h" +#include "../advection/kernel/RK4AdvectionKernel.h" +#include "../advection/kernel/SnapBoundaryConditionKernel.h" +using namespace std; + MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); + + cout << "Reading data..." << endl; + string dataPath = "../../../../data"; + shared_ptr uvGrid = make_shared(dataPath); + auto kernelRK4 = make_unique(uvGrid); + auto kernelRK4BoundaryChecked = make_unique(std::move(kernelRK4), uvGrid); + cout << "Starting vtk..." << endl; + + auto l = new LGlyphLayer(uvGrid, std::move(kernelRK4BoundaryChecked)); + // l->spoofPoints(); + l->setDt(3600); + // TODO: implement feature to call this function on widget + // l->cycleGlyphStyle(); + + Program *program = this->ui->getProgram(); + program->addLayer(new BackgroundImage(dataPath + "/map_qgis_1035.png")); + // TODO: implement feature to cycle between layers thru QT + program->addLayer(new EGlyphLayer(uvGrid)); + program->addLayer(new EColLayer(uvGrid)); + program->addLayer(l); + + program->setupInteractions(); } -MainWindow::~MainWindow() { delete ui; } - -void MainWindow::showAboutDialog() -{ - QMessageBox::information( - this, "About", - "interactive particle in-fluid simulation program for surface level advection."); +MainWindow::~MainWindow() { + delete ui; } -void MainWindow::showOpenFileDialog() -{ - QString fileName = QFileDialog::getOpenFileName(this, tr("Open file"), "", - "VTK Files (*.vtk)"); - // Open file - QFile file(fileName); - file.open(QIODevice::ReadOnly); +void MainWindow::on_FirstButton_clicked(bool checked) { + if (checked) { - // Return on Cancel - if (!file.exists()) - return; - - openFile(fileName); + } } -void MainWindow::openFile(const QString& fileName) -{ - ui->sceneWidget->removeDataSet(); - // Create reader - vtkSmartPointer reader = vtkSmartPointer::New(); - reader->SetFileName(fileName.toStdString().c_str()); +void MainWindow::on_SecondButton_clicked(bool checked) { + if (checked) { - // Read the file - reader->Update(); - - // Add data set to 3D view - vtkSmartPointer dataSet = reader->GetOutput(); - if (dataSet != nullptr) { - ui->sceneWidget->addDataSet(reader->GetOutput()); - } + } } + + +void MainWindow::on_ComplentaryButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_ContrastingButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_MonochromaticButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_SaturateButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_DesaturateButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_CircleButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_TriangleButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_SquareButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_HexagonButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_FullySampledButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_RegularlySubsampledButton_clicked(bool checked) { + if (checked) { + + } +} + + +void MainWindow::on_IregularlySampledButton_clicked(bool checked) { + if (checked) { + + }} + + diff --git a/particle-track-and-trace/src/QT/MainWindow.h b/particle-track-and-trace/src/QT/MainWindow.h index 679c0dc..38ef8f9 100644 --- a/particle-track-and-trace/src/QT/MainWindow.h +++ b/particle-track-and-trace/src/QT/MainWindow.h @@ -14,19 +14,21 @@ public: explicit MainWindow(QWidget* parent = 0); ~MainWindow(); -public slots: - //! Show the 'About this application' dialog - void showAboutDialog(); - - //! Show the 'Open file...' dialog - void showOpenFileDialog(); - -protected: - //! Open a file - /*! - \param[in] fileName The name of the file including the path - */ - void openFile(const QString& fileName); +private slots: + void on_FirstButton_clicked(bool checked); + void on_SecondButton_clicked(bool checked); + void on_ComplentaryButton_clicked(bool checked); + void on_ContrastingButton_clicked(bool checked); + void on_MonochromaticButton_clicked(bool checked); + void on_SaturateButton_clicked(bool checked); + void on_DesaturateButton_clicked(bool checked); + void on_CircleButton_clicked(bool checked); + void on_TriangleButton_clicked(bool checked); + void on_SquareButton_clicked(bool checked); + void on_HexagonButton_clicked(bool checked); + void on_FullySampledButton_clicked(bool checked); + void on_RegularlySubsampledButton_clicked(bool checked); + void on_IregularlySampledButton_clicked(bool checked); private: Ui::MainWindow* ui; diff --git a/particle-track-and-trace/src/QT/MainWindow.ui b/particle-track-and-trace/src/QT/MainWindow.ui index 6865dec..95eb54a 100644 --- a/particle-track-and-trace/src/QT/MainWindow.ui +++ b/particle-track-and-trace/src/QT/MainWindow.ui @@ -1,210 +1,355 @@ - MainWindow + MainWindow 0 0 - 800 - 600 + 1048 + 772 - Qt VTK Viewer + Simulation - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - + + + + + + + 0 + 0 + + + + + 220 + 0 + + + + + 280 + 16777215 + + + + Settings + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 500 + 300 + + + + Technique + + + + + + ECol + LGlyph + + + true + + + + + + + EGlyph + LCol + + + false + + + + + + + + + + + 0 + 550 + + + + Channel Options + + + + + 0 + 30 + 300 + 120 + + + + + 0 + 0 + + + + + 250 + 0 + + + + + 500 + 120 + + + + Color + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + + + + + + Complementary + + + + + + + + 0 + 0 + + + + Contrasting + + + + + + + Monochromatic + + + + + + + + + 0 + 160 + 269 + 100 + + + + + 0 + 0 + + + + + 260 + 0 + + + + + 500 + 100 + + + + Saturation + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + + + + + + Fully saturated + + + + + + + Desaturated + + + + + + + + + 0 + 270 + 260 + 150 + + + + + 0 + 0 + + + + + 260 + 0 + + + + + 500 + 150 + + + + Glyph Shape + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + + + + + + Circle + + + + + + + Triangle + + + + + + + Square + + + + + + + Hexagon + + + + + + + + + 0 + 430 + 260 + 120 + + + + + 0 + 0 + + + + + 260 + 0 + + + + + 500 + 120 + + + + Glyph count + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + + + + + + Fully sampled + + + + + + + Regularly subsampled + + + + + + + Irregularly sampled + + + + + + + + + + + + - - - - 0 - 0 - 800 - 21 - - - - - File - - - - - - - - Help - - - - - - - - - - toolBar - - - TopToolBarArea - - - false - - - - - - - - :/icons/open_file.png:/icons/open_file.png - - - Open file... - - - Open file... - - - Ctrl+O - - - - - - :/icons/zoom_to.png:/icons/zoom_to.png - - - Zoom to extent - - - Zoom to extent - - - - - - :/icons/quit.png:/icons/quit.png - - - Quit - - - Ctrl+Q - - - - - - :/icons/about.png:/icons/about.png - - - About - - + - SceneWidget - QOpenGLWidget -
scenewidget.h
- - zoomToExtent() - + MainView + QVTKOpenGLNativeWidget +
Program.h
- - - - - - actionOpenFile - triggered() - MainWindow - showOpenFileDialog() - - - -1 - -1 - - - 399 - 299 - - - - - actionQuit - triggered() - MainWindow - close() - - - -1 - -1 - - - 399 - 299 - - - - - actionZoomToExtent - triggered() - sceneWidget - zoomToExtent() - - - -1 - -1 - - - 399 - 314 - - - - - actionAbout - triggered() - MainWindow - showAboutDialog() - - - -1 - -1 - - - 399 - 299 - - - - - - showOpenFileDialog() - showAboutDialog() - + +
diff --git a/particle-track-and-trace/src/QT/ui_mainwindow.h b/particle-track-and-trace/src/QT/ui_mainwindow.h new file mode 100644 index 0000000..2816e24 --- /dev/null +++ b/particle-track-and-trace/src/QT/ui_mainwindow.h @@ -0,0 +1,282 @@ +/******************************************************************************** +** Form generated from reading UI file 'MainWindow.ui' +** +** Created by: Qt User Interface Compiler version 5.15.13 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_MAINWINDOW_H +#define UI_MAINWINDOW_H + +#include "../Program.h" +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_MainWindow +{ +public: + QWidget *centralWidget; + QHBoxLayout *horizontalLayout; + QGroupBox *settingsBox; + QVBoxLayout *verticalLayout_3; + QGroupBox *TechniqueBox; + QVBoxLayout *verticalLayout_2; + QRadioButton *FirstButton; + QRadioButton *SecondButton; + QGroupBox *ChannelBox; + QGroupBox *ColourBox; + QVBoxLayout *verticalLayout_12; + QRadioButton *ComplementaryButton; + QRadioButton *ContrastingButton; + QRadioButton *MonochromaticButton; + QGroupBox *SaturationBox; + QVBoxLayout *verticalLayout_13; + QRadioButton *SaturateButton; + QRadioButton *DesaturateButton; + QGroupBox *GlyphBox; + QVBoxLayout *verticalLayout_14; + QRadioButton *CircleButton; + QRadioButton *TriangleButton; + QRadioButton *SquareButton; + QRadioButton *HexagonButton; + QGroupBox *GlyphBox_2; + QVBoxLayout *verticalLayout_16; + QRadioButton *FullySampledButton; + QRadioButton *RegularlySubsampledButton; + QRadioButton *IregularlySubsampledButton; + Program *program; + + Program* getProgram() { + return program; + } + + void setupUi(QMainWindow *MainWindow) + { + if (MainWindow->objectName().isEmpty()) + MainWindow->setObjectName(QString::fromUtf8("MainWindow")); + MainWindow->resize(1048, 772); + centralWidget = new QWidget(MainWindow); + centralWidget->setObjectName(QString::fromUtf8("centralWidget")); + horizontalLayout = new QHBoxLayout(centralWidget); + horizontalLayout->setSpacing(6); + horizontalLayout->setContentsMargins(11, 11, 11, 11); + horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + settingsBox = new QGroupBox(centralWidget); + settingsBox->setObjectName(QString::fromUtf8("settingsBox")); + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(settingsBox->sizePolicy().hasHeightForWidth()); + settingsBox->setSizePolicy(sizePolicy); + settingsBox->setMinimumSize(QSize(220, 0)); + settingsBox->setMaximumSize(QSize(280, 16777215)); + verticalLayout_3 = new QVBoxLayout(settingsBox); + verticalLayout_3->setSpacing(6); + verticalLayout_3->setContentsMargins(11, 11, 11, 11); + verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3")); + TechniqueBox = new QGroupBox(settingsBox); + TechniqueBox->setObjectName(QString::fromUtf8("TechniqueBox")); + sizePolicy.setHeightForWidth(TechniqueBox->sizePolicy().hasHeightForWidth()); + TechniqueBox->setSizePolicy(sizePolicy); + TechniqueBox->setMinimumSize(QSize(0, 0)); + TechniqueBox->setMaximumSize(QSize(500, 100)); + verticalLayout_2 = new QVBoxLayout(TechniqueBox); + verticalLayout_2->setSpacing(6); + verticalLayout_2->setContentsMargins(11, 11, 11, 11); + verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + FirstButton = new QRadioButton(TechniqueBox); + FirstButton->setObjectName(QString::fromUtf8("FirstButton")); + FirstButton->setChecked(true); + + verticalLayout_2->addWidget(FirstButton); + + SecondButton = new QRadioButton(TechniqueBox); + SecondButton->setObjectName(QString::fromUtf8("SecondButton")); + SecondButton->setChecked(false); + + verticalLayout_2->addWidget(SecondButton); + + + verticalLayout_3->addWidget(TechniqueBox); + + ChannelBox = new QGroupBox(settingsBox); + ChannelBox->setObjectName(QString::fromUtf8("ChannelBox")); + ChannelBox->setMinimumSize(QSize(0, 550)); + ColourBox = new QGroupBox(ChannelBox); + ColourBox->setObjectName(QString::fromUtf8("ColourBox")); + ColourBox->setGeometry(QRect(0, 30, 300, 120)); + sizePolicy.setHeightForWidth(ColourBox->sizePolicy().hasHeightForWidth()); + ColourBox->setSizePolicy(sizePolicy); + ColourBox->setMinimumSize(QSize(250, 0)); + ColourBox->setMaximumSize(QSize(500, 120)); + ColourBox->setAlignment(Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter); + verticalLayout_12 = new QVBoxLayout(ColourBox); + verticalLayout_12->setSpacing(6); + verticalLayout_12->setContentsMargins(11, 11, 11, 11); + verticalLayout_12->setObjectName(QString::fromUtf8("verticalLayout_12")); + ComplementaryButton = new QRadioButton(ColourBox); + ComplementaryButton->setObjectName(QString::fromUtf8("ComplementaryButton")); + + verticalLayout_12->addWidget(ComplementaryButton); + + ContrastingButton = new QRadioButton(ColourBox); + ContrastingButton->setObjectName(QString::fromUtf8("ContrastingButton")); + QSizePolicy sizePolicy1(QSizePolicy::Maximum, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(ContrastingButton->sizePolicy().hasHeightForWidth()); + ContrastingButton->setSizePolicy(sizePolicy1); + + verticalLayout_12->addWidget(ContrastingButton); + + MonochromaticButton = new QRadioButton(ColourBox); + MonochromaticButton->setObjectName(QString::fromUtf8("MonochromaticButton")); + + verticalLayout_12->addWidget(MonochromaticButton); + + SaturationBox = new QGroupBox(ChannelBox); + SaturationBox->setObjectName(QString::fromUtf8("SaturationBox")); + SaturationBox->setGeometry(QRect(0, 160, 269, 100)); + sizePolicy.setHeightForWidth(SaturationBox->sizePolicy().hasHeightForWidth()); + SaturationBox->setSizePolicy(sizePolicy); + SaturationBox->setMinimumSize(QSize(260, 0)); + SaturationBox->setMaximumSize(QSize(500, 100)); + SaturationBox->setAlignment(Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter); + verticalLayout_13 = new QVBoxLayout(SaturationBox); + verticalLayout_13->setSpacing(6); + verticalLayout_13->setContentsMargins(11, 11, 11, 11); + verticalLayout_13->setObjectName(QString::fromUtf8("verticalLayout_13")); + SaturateButton = new QRadioButton(SaturationBox); + SaturateButton->setObjectName(QString::fromUtf8("SaturateButton")); + + verticalLayout_13->addWidget(SaturateButton); + + DesaturateButton = new QRadioButton(SaturationBox); + DesaturateButton->setObjectName(QString::fromUtf8("DesaturateButton")); + + verticalLayout_13->addWidget(DesaturateButton); + + GlyphBox = new QGroupBox(ChannelBox); + GlyphBox->setObjectName(QString::fromUtf8("GlyphBox")); + GlyphBox->setGeometry(QRect(0, 270, 260, 150)); + sizePolicy.setHeightForWidth(GlyphBox->sizePolicy().hasHeightForWidth()); + GlyphBox->setSizePolicy(sizePolicy); + GlyphBox->setMinimumSize(QSize(260, 0)); + GlyphBox->setMaximumSize(QSize(500, 150)); + GlyphBox->setAlignment(Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter); + verticalLayout_14 = new QVBoxLayout(GlyphBox); + verticalLayout_14->setSpacing(6); + verticalLayout_14->setContentsMargins(11, 11, 11, 11); + verticalLayout_14->setObjectName(QString::fromUtf8("verticalLayout_14")); + CircleButton = new QRadioButton(GlyphBox); + CircleButton->setObjectName(QString::fromUtf8("CircleButton")); + + verticalLayout_14->addWidget(CircleButton); + + TriangleButton = new QRadioButton(GlyphBox); + TriangleButton->setObjectName(QString::fromUtf8("TriangleButton")); + + verticalLayout_14->addWidget(TriangleButton); + + SquareButton = new QRadioButton(GlyphBox); + SquareButton->setObjectName(QString::fromUtf8("SquareButton")); + + verticalLayout_14->addWidget(SquareButton); + + HexagonButton = new QRadioButton(GlyphBox); + HexagonButton->setObjectName(QString::fromUtf8("HexagonButton")); + + verticalLayout_14->addWidget(HexagonButton); + + GlyphBox_2 = new QGroupBox(ChannelBox); + GlyphBox_2->setObjectName(QString::fromUtf8("GlyphBox_2")); + GlyphBox_2->setGeometry(QRect(0, 430, 260, 120)); + QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy2.setHorizontalStretch(0); + sizePolicy2.setVerticalStretch(0); + sizePolicy2.setHeightForWidth(GlyphBox_2->sizePolicy().hasHeightForWidth()); + GlyphBox_2->setSizePolicy(sizePolicy2); + GlyphBox_2->setMinimumSize(QSize(260, 0)); + GlyphBox_2->setMaximumSize(QSize(500, 120)); + GlyphBox_2->setAlignment(Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter); + verticalLayout_16 = new QVBoxLayout(GlyphBox_2); + verticalLayout_16->setSpacing(6); + verticalLayout_16->setContentsMargins(11, 11, 11, 11); + verticalLayout_16->setObjectName(QString::fromUtf8("verticalLayout_16")); + FullySampledButton = new QRadioButton(GlyphBox_2); + FullySampledButton->setObjectName(QString::fromUtf8("FullySampledButton")); + + verticalLayout_16->addWidget(FullySampledButton); + + RegularlySubsampledButton = new QRadioButton(GlyphBox_2); + RegularlySubsampledButton->setObjectName(QString::fromUtf8("RegularlySampledButton")); + + verticalLayout_16->addWidget(RegularlySubsampledButton); + + IregularlySubsampledButton = new QRadioButton(GlyphBox_2); + IregularlySubsampledButton->setObjectName(QString::fromUtf8("IregularlySubsampledButton")); + + verticalLayout_16->addWidget(IregularlySubsampledButton); + + + verticalLayout_3->addWidget(ChannelBox); + + + horizontalLayout->addWidget(settingsBox); + + program = new Program(centralWidget); + program->setObjectName(QString::fromUtf8("program")); + + horizontalLayout->addWidget(program); + + MainWindow->setCentralWidget(centralWidget); + + retranslateUi(MainWindow); + + QMetaObject::connectSlotsByName(MainWindow); + } // setupUi + + void retranslateUi(QMainWindow *MainWindow) + { + MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "Simulation", nullptr)); + settingsBox->setTitle(QCoreApplication::translate("MainWindow", "Settings", nullptr)); + TechniqueBox->setTitle(QCoreApplication::translate("MainWindow", "Technique", nullptr)); + FirstButton->setText(QCoreApplication::translate("MainWindow", "ECol + LGlyph", nullptr)); + SecondButton->setText(QCoreApplication::translate("MainWindow", "EGlyph + LCol", nullptr)); + ChannelBox->setTitle(QCoreApplication::translate("MainWindow", "Channel Options", nullptr)); + ColourBox->setTitle(QCoreApplication::translate("MainWindow", "Color", nullptr)); + ComplementaryButton->setText(QCoreApplication::translate("MainWindow", "Complementary ", nullptr)); + ContrastingButton->setText(QCoreApplication::translate("MainWindow", "Contrasting", nullptr)); + MonochromaticButton->setText(QCoreApplication::translate("MainWindow", "Monochromatic", nullptr)); + SaturationBox->setTitle(QCoreApplication::translate("MainWindow", "Saturation", nullptr)); + SaturateButton->setText(QCoreApplication::translate("MainWindow", "Fully saturated", nullptr)); + DesaturateButton->setText(QCoreApplication::translate("MainWindow", "Desaturated", nullptr)); + GlyphBox->setTitle(QCoreApplication::translate("MainWindow", "Glyph Shape", nullptr)); + CircleButton->setText(QCoreApplication::translate("MainWindow", "Circle", nullptr)); + TriangleButton->setText(QCoreApplication::translate("MainWindow", "Triangle", nullptr)); + SquareButton->setText(QCoreApplication::translate("MainWindow", "Square", nullptr)); + HexagonButton->setText(QCoreApplication::translate("MainWindow", "Hexagon", nullptr)); + GlyphBox_2->setTitle(QCoreApplication::translate("MainWindow", "Glyph count", nullptr)); + FullySampledButton->setText(QCoreApplication::translate("MainWindow", "Fully sampled", nullptr)); + RegularlySubsampledButton->setText(QCoreApplication::translate("MainWindow", "Regularly subsampled", nullptr)); + IregularlySubsampledButton->setText(QCoreApplication::translate("MainWindow", "Irregularly sampled", nullptr)); + } // retranslateUi + +}; + +namespace Ui { + class MainWindow: public Ui_MainWindow {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_MAINWINDOW_H diff --git a/particle-track-and-trace/src/main.cpp b/particle-track-and-trace/src/main.cpp index b49b4f0..0f7d692 100644 --- a/particle-track-and-trace/src/main.cpp +++ b/particle-track-and-trace/src/main.cpp @@ -40,35 +40,37 @@ int main(int argc, char* argv[]) { QApplication app(argc, argv); // Main window. - QMainWindow mainWindow; + MainWindow mainWindow; mainWindow.resize(1200, 900); + mainWindow.show(); + return app.exec(); + // Control area. - QDockWidget controlDock; - mainWindow.addDockWidget(Qt::LeftDockWidgetArea, &controlDock); - - QLabel controlDockTitle("Control Dock"); - controlDockTitle.setMargin(20); - controlDock.setTitleBarWidget(&controlDockTitle); - - QPointer dockLayout = new QVBoxLayout(); - QWidget layoutContainer; - layoutContainer.setLayout(dockLayout); - controlDock.setWidget(&layoutContainer); - - QPushButton randomizeButton; - randomizeButton.setText("Randomize"); - dockLayout->addWidget(&randomizeButton); + // QDockWidget controlDock; + // mainWindow.addDockWidget(Qt::LeftDockWidgetArea, &controlDock); + // + // QLabel controlDockTitle("Control Dock"); + // controlDockTitle.setMargin(20); + // controlDock.setTitleBarWidget(&controlDockTitle); + // + // QPointer dockLayout = new QVBoxLayout(); + // QWidget layoutContainer; + // layoutContainer.setLayout(dockLayout); + // controlDock.setWidget(&layoutContainer); + // + // QPushButton randomizeButton; + // randomizeButton.setText("Randomize"); + // dockLayout->addWidget(&randomizeButton); // Render area. - QPointer vtkRenderWidget = - new QVTKOpenGLNativeWidget(); - mainWindow.setCentralWidget(vtkRenderWidget); + // QPointer vtkRenderWidget = + // new QVTKOpenGLNativeWidget(); + // mainWindow.setCentralWidget(vtkRenderWidget); // VTK part. - vtkNew window; - vtkRenderWidget->setRenderWindow(window.Get()); - + // vtkNew window; + // vtkRenderWidget->setRenderWindow(window.Get()); cout << "Reading data..." << endl; string dataPath = "../../../../data"; @@ -83,7 +85,7 @@ int main(int argc, char* argv[]) { // TODO: implement feature to call this function on widget // l->cycleGlyphStyle(); - unique_ptr program = make_unique(DT, window); + unique_ptr program = make_unique(); program->addLayer(new BackgroundImage(dataPath + "/map_qgis_1035.png")); // TODO: implement feature to cycle between layers thru QT program->addLayer(new EGlyphLayer(uvGrid)); From 19166cc14d122685673e59a44a6979a696cdbda6 Mon Sep 17 00:00:00 2001 From: djairoh Date: Sun, 26 May 2024 11:36:24 +0200 Subject: [PATCH 7/8] setup for qdiget callback done --- particle-track-and-trace/src/QT/MainWindow.cpp | 10 ++++++++-- particle-track-and-trace/src/QT/ui_mainwindow.h | 4 ---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/particle-track-and-trace/src/QT/MainWindow.cpp b/particle-track-and-trace/src/QT/MainWindow.cpp index 09245d8..18fad0b 100644 --- a/particle-track-and-trace/src/QT/MainWindow.cpp +++ b/particle-track-and-trace/src/QT/MainWindow.cpp @@ -36,7 +36,7 @@ MainWindow::MainWindow(QWidget* parent) // TODO: implement feature to call this function on widget // l->cycleGlyphStyle(); - Program *program = this->ui->getProgram(); + Program *program = this->ui->program; program->addLayer(new BackgroundImage(dataPath + "/map_qgis_1035.png")); // TODO: implement feature to cycle between layers thru QT program->addLayer(new EGlyphLayer(uvGrid)); @@ -51,15 +51,21 @@ MainWindow::~MainWindow() { } +/* -------------------------------------------------------------------- + * + QTWidget callbacks + + * --------------------------------------------------------------------*/ + + void MainWindow::on_FirstButton_clicked(bool checked) { if (checked) { - + cout << "clicked button 1!" << endl; } } void MainWindow::on_SecondButton_clicked(bool checked) { if (checked) { + cout << "clicked button 2!" << endl; } } diff --git a/particle-track-and-trace/src/QT/ui_mainwindow.h b/particle-track-and-trace/src/QT/ui_mainwindow.h index 2816e24..26f8ad0 100644 --- a/particle-track-and-trace/src/QT/ui_mainwindow.h +++ b/particle-track-and-trace/src/QT/ui_mainwindow.h @@ -55,10 +55,6 @@ public: QRadioButton *IregularlySubsampledButton; Program *program; - Program* getProgram() { - return program; - } - void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) From 3725576f6b312de14765a08a85040649a3b65360 Mon Sep 17 00:00:00 2001 From: djairoh Date: Sun, 26 May 2024 11:38:47 +0200 Subject: [PATCH 8/8] fix: spelling --- particle-track-and-trace/src/QT/MainWindow.cpp | 4 ++-- particle-track-and-trace/src/QT/MainWindow.h | 4 ++-- particle-track-and-trace/src/QT/ui_mainwindow.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/particle-track-and-trace/src/QT/MainWindow.cpp b/particle-track-and-trace/src/QT/MainWindow.cpp index 18fad0b..3a5afee 100644 --- a/particle-track-and-trace/src/QT/MainWindow.cpp +++ b/particle-track-and-trace/src/QT/MainWindow.cpp @@ -71,7 +71,7 @@ void MainWindow::on_SecondButton_clicked(bool checked) { } -void MainWindow::on_ComplentaryButton_clicked(bool checked) { +void MainWindow::on_ComplementaryButton_clicked(bool checked) { if (checked) { } @@ -148,7 +148,7 @@ void MainWindow::on_RegularlySubsampledButton_clicked(bool checked) { } -void MainWindow::on_IregularlySampledButton_clicked(bool checked) { +void MainWindow::on_IregularlySubsampledButton_clicked(bool checked) { if (checked) { }} diff --git a/particle-track-and-trace/src/QT/MainWindow.h b/particle-track-and-trace/src/QT/MainWindow.h index 38ef8f9..ef9a5cf 100644 --- a/particle-track-and-trace/src/QT/MainWindow.h +++ b/particle-track-and-trace/src/QT/MainWindow.h @@ -17,7 +17,7 @@ public: private slots: void on_FirstButton_clicked(bool checked); void on_SecondButton_clicked(bool checked); - void on_ComplentaryButton_clicked(bool checked); + void on_ComplementaryButton_clicked(bool checked); void on_ContrastingButton_clicked(bool checked); void on_MonochromaticButton_clicked(bool checked); void on_SaturateButton_clicked(bool checked); @@ -28,7 +28,7 @@ private slots: void on_HexagonButton_clicked(bool checked); void on_FullySampledButton_clicked(bool checked); void on_RegularlySubsampledButton_clicked(bool checked); - void on_IregularlySampledButton_clicked(bool checked); + void on_IregularlySubsampledButton_clicked(bool checked); private: Ui::MainWindow* ui; diff --git a/particle-track-and-trace/src/QT/ui_mainwindow.h b/particle-track-and-trace/src/QT/ui_mainwindow.h index 26f8ad0..dd3ff49 100644 --- a/particle-track-and-trace/src/QT/ui_mainwindow.h +++ b/particle-track-and-trace/src/QT/ui_mainwindow.h @@ -214,7 +214,7 @@ public: verticalLayout_16->addWidget(FullySampledButton); RegularlySubsampledButton = new QRadioButton(GlyphBox_2); - RegularlySubsampledButton->setObjectName(QString::fromUtf8("RegularlySampledButton")); + RegularlySubsampledButton->setObjectName(QString::fromUtf8("RegularlySubsampledButton")); verticalLayout_16->addWidget(RegularlySubsampledButton);