refactor of VtkCallbackCommand to be its' own class
This commit is contained in:
parent
b83f49b4ad
commit
da17aa5cfa
|
|
@ -42,6 +42,8 @@ add_executable(VtkBase MACOSX_BUNDLE main.cpp
|
||||||
helperClasses/LGlyphLayer.h
|
helperClasses/LGlyphLayer.h
|
||||||
helperClasses/Program.cpp
|
helperClasses/Program.cpp
|
||||||
helperClasses/Program.h
|
helperClasses/Program.h
|
||||||
|
commands/TimerCallbackCommand.h
|
||||||
|
commands/TimerCallbackCommand.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "TimerCallbackCommand.h"
|
||||||
|
#include "../helperClasses/Program.h"
|
||||||
|
|
||||||
|
|
||||||
|
// TimerCallbackCommand::TimerCallbackCommand() : dt(3600), maxTime(3600*24*365), time(0) {}
|
||||||
|
|
||||||
|
TimerCallbackCommand *New() {
|
||||||
|
TimerCallbackCommand *cb = new TimerCallbackCommand();
|
||||||
|
cb->setDefaults();
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerCallbackCommand::Execute(vtkObject *caller, long unsigned int eventId, void* clientData, void* callData) {
|
||||||
|
this->time += this->dt;
|
||||||
|
|
||||||
|
if (this->time >= this->maxTime) {
|
||||||
|
return;
|
||||||
|
// TODO: how do we deal with reaching the end of the simulated dataset? Do we just stop simulating, loop back around? What about the location of the particles in this case? Just some ideas to consider, but we should iron this out pretty soon.
|
||||||
|
}
|
||||||
|
|
||||||
|
((Program *)clientData)->updateData(this->time);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef TIMERCALLBACKCOMMAND_H
|
||||||
|
#define TIMERCALLBACKCOMMAND_H
|
||||||
|
|
||||||
|
#include <vtkCallbackCommand.h>
|
||||||
|
#include "../helperClasses/Program.h"
|
||||||
|
|
||||||
|
class TimerCallbackCommand : public vtkCallbackCommand {
|
||||||
|
public:
|
||||||
|
TimerCallbackCommand();
|
||||||
|
static TimerCallbackCommand* New(Program *program);
|
||||||
|
void Execute(vtkObject* caller, unsigned long eventId, void* vtkNotUsed(callData)) override;
|
||||||
|
|
||||||
|
void setDefaults();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
int time;
|
||||||
|
int dt;
|
||||||
|
int maxTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "TimerCallbackCommand.h"
|
||||||
|
#include "../helperClasses/Program.h"
|
||||||
|
|
||||||
|
|
||||||
|
TimerCallbackCommand::TimerCallbackCommand() : dt(3600), maxTime(3600*24*365), time(0) {}
|
||||||
|
|
||||||
|
TimerCallbackCommand* TimerCallbackCommand::New(Program *program) {
|
||||||
|
TimerCallbackCommand *cb = new TimerCallbackCommand();
|
||||||
|
cb->setProgram(program);
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerCallbackCommand::Execute(vtkObject* caller, unsigned long eventId, void* vtkNotUsed(callData)) {
|
||||||
|
cout << this->time << " " << this->maxTime << endl;
|
||||||
|
|
||||||
|
this->time += this->dt;
|
||||||
|
|
||||||
|
if (this->time >= this->maxTime) {
|
||||||
|
return;
|
||||||
|
// TODO: how do we deal with reaching the end of the simulated dataset? Do we just stop simulating, loop back around? What about the location of the particles in this case? Just some ideas to consider, but we should iron this out pretty soon.
|
||||||
|
}
|
||||||
|
|
||||||
|
this->program->updateData(this->time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void TimerCallbackCommand::setProgram(Program *program) {
|
||||||
|
this->program = program;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef TIMERCALLBACKCOMMAND_H
|
||||||
|
#define TIMERCALLBACKCOMMAND_H
|
||||||
|
|
||||||
|
#include <vtkCallbackCommand.h>
|
||||||
|
#include "../helperClasses/Program.h"
|
||||||
|
|
||||||
|
class TimerCallbackCommand : public vtkCallbackCommand {
|
||||||
|
public:
|
||||||
|
TimerCallbackCommand();
|
||||||
|
static TimerCallbackCommand* New(Program *program);
|
||||||
|
void Execute(vtkObject* caller, unsigned long eventId, void* vtkNotUsed(callData)) override;
|
||||||
|
|
||||||
|
void setProgram(Program *program);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int time;
|
||||||
|
int dt;
|
||||||
|
int maxTime;
|
||||||
|
Program *program;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -48,6 +48,8 @@ EGlyphLayer::EGlyphLayer() {
|
||||||
this->ren->InteractiveOff();
|
this->ren->InteractiveOff();
|
||||||
|
|
||||||
this->data = vtkSmartPointer<vtkPolyData>::New();
|
this->data = vtkSmartPointer<vtkPolyData>::New();
|
||||||
|
this->direction = vtkSmartPointer<vtkDoubleArray>::New();
|
||||||
|
this->direction->SetName("direction");
|
||||||
readCoordinates();
|
readCoordinates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,22 +57,23 @@ EGlyphLayer::EGlyphLayer() {
|
||||||
void EGlyphLayer::readCoordinates() {
|
void EGlyphLayer::readCoordinates() {
|
||||||
vtkNew<vtkPoints> points;
|
vtkNew<vtkPoints> points;
|
||||||
auto [times, lats, lons] = readGrid(); // FIXME: import Robin's readData function and use it
|
auto [times, lats, lons] = readGrid(); // FIXME: import Robin's readData function and use it
|
||||||
vtkNew<vtkDoubleArray> direction;
|
this->numLats = lats.size();
|
||||||
direction->SetName("direction");
|
this->numLons = lons.size();
|
||||||
direction->SetNumberOfComponents(3);
|
|
||||||
direction->SetNumberOfTuples(67*116); //FIXME: use robins function to get num of points
|
this->direction->SetNumberOfComponents(3);
|
||||||
points->Allocate(67*116);
|
this->direction->SetNumberOfTuples(numLats*numLons);
|
||||||
|
points->Allocate(numLats*numLons);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (double lat : lats) {
|
for (double lat : lats) {
|
||||||
for (double lon : lons) {
|
for (double lon : lons) {
|
||||||
direction->SetTuple3(i, 0.45, 0.90, 0); //FIXME: read this info from file; figure out how to update it dynamically
|
direction->SetTuple3(i, 0.45, 0.90, 0); //FIXME: read this info from file
|
||||||
points->InsertPoint(i++, (lat*1000-46125)/25, (lon*1000+15875)/43.5, 0); // FIXME: counts on fixed window geometry to map properly; refactor to make use of active window geometry.
|
points->InsertPoint(i++, (lat*1000-46125)/25, (lon*1000+15875)/43.5, 0); // FIXME: counts on fixed window geometry to map properly; refactor to make use of active window geometry.
|
||||||
// see also https://vtk.org/doc/nightly/html/classvtkPolyDataMapper2D.html
|
// see also https://vtk.org/doc/nightly/html/classvtkPolyDataMapper2D.html
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->data->SetPoints(points);
|
this->data->SetPoints(points);
|
||||||
this->data->GetPointData()->AddArray(direction);
|
this->data->GetPointData()->AddArray(this->direction);
|
||||||
this->data->GetPointData()->SetActiveVectors("direction");
|
this->data->GetPointData()->SetActiveVectors("direction");
|
||||||
|
|
||||||
vtkNew<vtkGlyphSource2D> arrowSource;
|
vtkNew<vtkGlyphSource2D> arrowSource;
|
||||||
|
|
@ -101,10 +104,13 @@ void EGlyphLayer::readCoordinates() {
|
||||||
actor->GetProperty()->SetColor(0,0,0);
|
actor->GetProperty()->SetColor(0,0,0);
|
||||||
actor->GetProperty()->SetOpacity(0.2);
|
actor->GetProperty()->SetOpacity(0.2);
|
||||||
|
|
||||||
this->ren->AddActor(actor);
|
this->ren->AddActor(actor) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EGlyphLayer::updateData(int t) {
|
void EGlyphLayer::updateData(int t) {
|
||||||
|
for (int i=0; i < numLats*numLons; i++) {
|
||||||
|
this->direction->SetTuple3(i, std::cos(t), std::sin(t), 0); // FIXME: fetch data from file.
|
||||||
|
}
|
||||||
|
this->direction->Modified();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@
|
||||||
class EGlyphLayer : public Layer {
|
class EGlyphLayer : public Layer {
|
||||||
private:
|
private:
|
||||||
vtkSmartPointer<vtkPolyData> data;
|
vtkSmartPointer<vtkPolyData> data;
|
||||||
|
vtkSmartPointer<vtkDoubleArray> direction;
|
||||||
|
int numLats;
|
||||||
|
int numLons;
|
||||||
|
|
||||||
/** This private function sets up the initial coordinates for the glyphs in the dataset.
|
/** This private function sets up the initial coordinates for the glyphs in the dataset.
|
||||||
* It also reads some initial data to actually display.
|
* It also reads some initial data to actually display.
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ void LGlyphLayer::spoofPoints() {
|
||||||
|
|
||||||
// returns new coords for a point; used to test the updateData function
|
// returns new coords for a point; used to test the updateData function
|
||||||
std::pair<double, double> advect(int time, double lat, double lon) {
|
std::pair<double, double> advect(int time, double lat, double lon) {
|
||||||
return {lat+0.001, lon+0.001} ;
|
return {lat+0.1, lon+0.1} ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,23 @@
|
||||||
#include <vtkRenderWindow.h>
|
#include <vtkRenderWindow.h>
|
||||||
|
#include <vtkPointData.h>
|
||||||
|
#include <vtkDoubleArray.h>
|
||||||
|
#include <vtkGlyphSource2D.h>
|
||||||
|
#include <vtkRegularPolygonSource.h>
|
||||||
|
#include <vtkGlyph2D.h>
|
||||||
|
#include <vtkActor2D.h>
|
||||||
|
#include <vtkNamedColors.h>
|
||||||
|
#include <vtkPolyDataMapper2D.h>
|
||||||
|
#include <vtkPolyDataMapper.h>
|
||||||
|
#include <vtkProperty.h>
|
||||||
|
#include <vtkProperty2D.h>
|
||||||
|
#include <vtkVertexGlyphFilter.h>
|
||||||
|
#include <netcdf>
|
||||||
|
#include <vtkArrowSource.h>
|
||||||
#include <vtkNew.h>
|
#include <vtkNew.h>
|
||||||
#include <vtkCallbackCommand.h>
|
#include <vtkCallbackCommand.h>
|
||||||
|
|
||||||
#include "Program.h"
|
#include "Program.h"
|
||||||
|
#include "../commands/TimerCallbackCommand.h"
|
||||||
|
|
||||||
void Program::setWinProperties() {
|
void Program::setWinProperties() {
|
||||||
this->win->SetWindowName("Simulation");
|
this->win->SetWindowName("Simulation");
|
||||||
|
|
@ -15,15 +29,8 @@ void Program::setWinProperties() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::CallbackFunction(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData) {
|
|
||||||
((Program *)clientData)->lagrange->updateData(1);
|
|
||||||
((Program *)clientData)->win->Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Program::setupTimer() {
|
void Program::setupTimer() {
|
||||||
vtkNew<vtkCallbackCommand> callback;
|
auto callback = vtkSmartPointer<TimerCallbackCommand>::New(this);
|
||||||
callback->SetCallback(this->CallbackFunction);
|
|
||||||
callback->SetClientData(this);
|
callback->SetClientData(this);
|
||||||
this->interact->AddObserver(vtkCommand::TimerEvent, callback);
|
this->interact->AddObserver(vtkCommand::TimerEvent, callback);
|
||||||
this->interact->CreateRepeatingTimer(17); // 60 fps == 1000 / 60 == 16.7 ms per frame
|
this->interact->CreateRepeatingTimer(17); // 60 fps == 1000 / 60 == 16.7 ms per frame
|
||||||
|
|
@ -67,6 +74,14 @@ void Program::setLagrange(Layer *l) {
|
||||||
// void Program::addInteractionStyle(vtkInteractorStyle style);
|
// void Program::addInteractionStyle(vtkInteractorStyle style);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Program::updateData(int t) {
|
||||||
|
this->win->Render();
|
||||||
|
this->lagrange->updateData(t);
|
||||||
|
this->euler->updateData(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Program::render() {
|
void Program::render() {
|
||||||
this->win->Render();
|
this->win->Render();
|
||||||
this->interact->Start();
|
this->interact->Start();
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ private:
|
||||||
vtkSmartPointer<vtkRenderWindowInteractor> interact;
|
vtkSmartPointer<vtkRenderWindowInteractor> interact;
|
||||||
|
|
||||||
void setWinProperties();
|
void setWinProperties();
|
||||||
static void CallbackFunction(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData);
|
|
||||||
void setupTimer();
|
void setupTimer();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -27,6 +26,7 @@ public:
|
||||||
void setLagrange(Layer *l);
|
void setLagrange(Layer *l);
|
||||||
|
|
||||||
// void addInteractionStyle(vtkInteractorStyle style);
|
// void addInteractionStyle(vtkInteractorStyle style);
|
||||||
|
void updateData(int t);
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue