feat: refactor spawnpointcallback

This commit is contained in:
Djairo Hougee 2024-05-30 18:14:27 +02:00
parent c825e63762
commit 9ecdc5eb43
12 changed files with 206 additions and 85 deletions

View File

@ -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

View File

@ -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));

View File

@ -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);

View File

@ -0,0 +1,74 @@
#include <vtkVertex.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkCommand.h>
#include <vtkRenderWindow.h>
#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<vtkRenderWindowInteractor *>(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<double>(x), static_cast<double>(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 <float> (rand()) /( static_cast <float> (RAND_MAX/(this->lats[1] - this->lats[0])));
mod[1] = this->lons[0] + static_cast <float> (rand()) /( static_cast <float> (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> &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;
}

View File

@ -0,0 +1,30 @@
#ifndef MASSSPAWNPOINTCALLBACK_H
#define MASSSPAWNPOINTCALLBACK_H
#include <vtkCallbackCommand.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkAbstractTransform.h>
#include "SpawnPointCallback.h"
class MassSpawnPointCallback : public SpawnPointCallback {
public:
MassSpawnPointCallback();
static MassSpawnPointCallback *New();
void setUVGrid(const std::shared_ptr<UVGrid> &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

View File

@ -0,0 +1,49 @@
#include "SingularSpawnPointCallback.h"
#include <vtkVertex.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkCommand.h>
#include <vtkRenderWindow.h>
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<vtkRenderWindowInteractor *>(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<double>(x), static_cast<double>(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;
}

View File

@ -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

View File

@ -1,58 +1,9 @@
#include "SpawnPointCallback.h"
#include <vtkVertex.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkCommand.h>
#include <vtkRenderWindow.h>
#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<vtkRenderWindowInteractor *>(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<double>(x), static_cast<double>(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<vtkPoints> &points) {
this->points = points;
}

View File

@ -2,33 +2,17 @@
#define SPAWNPOINTCALLBACK_H
#include <memory>
#include <vtkCallbackCommand.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkAbstractTransform.h>
#include <vtkCallbackCommand.h>
#include <vtkIntArray.h>
#include <vtkPoints.h>
#include <vtkRenderer.h>
#include "../advection/UVGrid.h"
class SpawnPointCallback : public vtkCallbackCommand {
public:
static SpawnPointCallback *New();
SpawnPointCallback();
void setPoints(const vtkSmartPointer<vtkPoints> &points);
void setRen(const vtkSmartPointer<vtkRenderer> &ren);
void setBeached(const vtkSmartPointer<vtkIntArray> &parts);
void setAge(const vtkSmartPointer<vtkIntArray> &parts);
void setIdx(const vtkSmartPointer<vtkIntArray> &idx);
void setUVGrid(const std::shared_ptr<UVGrid> &uvGrid);
private:
protected:
vtkSmartPointer<vtkPoints> points;
vtkSmartPointer<vtkRenderer> ren;
vtkSmartPointer<vtkIntArray> particlesBeached;
@ -36,11 +20,19 @@ private:
vtkSmartPointer<vtkIntArray> lutIdx;
std::shared_ptr<UVGrid> uvGrid;
vtkSmartPointer<vtkAbstractTransform> inverseCartographicProjection;
void Execute(vtkObject *caller, unsigned long evId, void *callData) override;
bool dragging = false;
public:
virtual void setPoints(const vtkSmartPointer<vtkPoints> &points);
virtual void setRen(const vtkSmartPointer<vtkRenderer> &ren);
virtual void setBeached(const vtkSmartPointer<vtkIntArray> &parts);
virtual void setAge(const vtkSmartPointer<vtkIntArray> &parts);
virtual void setIdx(const vtkSmartPointer<vtkIntArray> &idx);
virtual void setUVGrid(const std::shared_ptr<UVGrid> &uvGrid);
};
#endif //SPAWNPOINTCALLBACK_H
#endif

View File

@ -1,5 +1,3 @@
#include "LColLayer.h"
#include "../commands/SpawnPointCallback.h"
#include <vtkActor2D.h>
#include <vtkCellData.h>
#include <vtkGlyph2D.h>
@ -19,6 +17,8 @@
#include <vtkRenderWindow.h>
#include <vtkCamera.h>
#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<SpawnPointCallback> LColLayer::createSpawnPointCallback() {
vtkNew<SpawnPointCallback> newPointCallBack;
vtkNew<MassSpawnPointCallback> newPointCallBack;
newPointCallBack->setPoints(this->points);
newPointCallBack->setRen(this->ren);
newPointCallBack->setUVGrid(this->uvGrid);

View File

@ -1,5 +1,5 @@
#include "LGlyphLayer.h"
#include "../commands/SpawnPointCallback.h"
#include "../commands/SingularSpawnPointCallback.h"
#include <vtkActor2D.h>
#include <vtkGlyph2D.h>
#include <vtkLookupTable.h>
@ -9,6 +9,7 @@
#include <vtkPolyDataMapper2D.h>
#include <vtkProperty.h>
#include <vtkProperty2D.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkInteractorStyle.h>
#include <vtkInteractorStyleUser.h>
@ -22,7 +23,7 @@
#include "luts.h"
vtkSmartPointer<SpawnPointCallback> LGlyphLayer::createSpawnPointCallback() {
vtkNew<SpawnPointCallback> newPointCallBack;
vtkNew<SingularSpawnPointCallback> newPointCallBack;
newPointCallBack->setPoints(this->points);
newPointCallBack->setRen(this->ren);
newPointCallBack->setUVGrid(this->uvGrid);

View File

@ -2,9 +2,7 @@
#include <QVTKOpenGLNativeWidget.h>
#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 <unsigned> (time(0)));
QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
QApplication app(argc, argv);