diff --git a/particle-track-and-trace/src/CMakeLists.txt b/particle-track-and-trace/src/CMakeLists.txt index ac28701..cf6696a 100644 --- a/particle-track-and-trace/src/CMakeLists.txt +++ b/particle-track-and-trace/src/CMakeLists.txt @@ -40,12 +40,16 @@ find_package(netCDF REQUIRED) add_executable(ParticleTrackTrace MACOSX_BUNDLE main.cpp layers/BackgroundImage.cpp layers/BackgroundImage.h + layers/EColLayer.cpp + layers/EColLayer.h layers/EGlyphLayer.cpp layers/EGlyphLayer.h layers/Layer.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 new file mode 100644 index 0000000..e6c5325 --- /dev/null +++ b/particle-track-and-trace/src/layers/EColLayer.cpp @@ -0,0 +1,144 @@ +#include "EColLayer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../CartographicTransformation.h" + +using namespace std; + + +EColLayer::EColLayer(std::shared_ptr uvGrid) { + this->ren = vtkSmartPointer::New(); + this->ren->SetLayer(1); + this->ren->InteractiveOff(); + + this->uvGrid = uvGrid; + this->numLats = uvGrid->lats.size(); + this->numLons = uvGrid->lons.size(); + + this->strength = vtkSmartPointer::New(); + this->strength->SetName("strength"); + this->strength->SetNumberOfComponents(1); + this->strength->SetNumberOfTuples((numLats-1)*(numLons-1)); + + readCoordinates(); +} + + +// TODO: Bit of a superfunction here; can do with some refactoring. +void EColLayer::readCoordinates() { + vtkNew points; + points->Allocate(numLats*numLons); + + vtkNew data; + data->SetPoints(points); + data->Allocate((numLats-1)*(numLons-1)); + + auto transformFilter = createCartographicTransformFilter(uvGrid); + auto transform = transformFilter->GetTransform(); + + int cellId = 0, pointId = 0; + int latIndex = 0, lonIndex = 0; + for (auto lon : uvGrid->lons) { + latIndex = 0; + 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); + + 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); + + double u=0, v=0; + for (int j=0; j < 2; j++ ) { + for (int k=0; k < 2; k++ ) { + auto [u1, v1] = (*uvGrid)[0, latIndex-j, lonIndex-k]; + u += u1; + v += v1; + } + } + u /= 4; + v /= 4; + this->strength->SetTuple1(cellId++, std::sqrt(u*u + v*v)); + } + latIndex++; + } + lonIndex++; + } + + data->GetCellData()->AddArray(this->strength); + data->GetCellData()->SetActiveScalars("strength"); + + vtkNew(mapper); + mapper->SetInputData(data); + mapper->Update(); + + vtkNew actor; + actor->SetMapper(mapper); + actor->GetProperty()->SetColor(0, 1, 0); + actor->GetProperty()->SetOpacity(0.2); + + // vtkNew act2; + // act2->SetMapper(mapper); + // act2->GetProperty()->SetRepresentationToWireframe(); + // ren->AddActor(act2); + + this->ren->AddActor(actor); +} + + +void EColLayer::updateData(int t) { + int i = 0; + for (int lon = 1; lon < uvGrid->lonSize; lon++) { + for (int lat = 1; lat < uvGrid->latSize; lat++) { + double u=0, v=0; + for (int j=0; j < 2; j++ ) { + for (int k=0; k < 2; k++ ) { + auto [u1, v1] = (*uvGrid)[t/3600, lat-j, lon-k]; + u += u1; + v += v1; + } + } + u /= 4; + v /= 4; + this->strength->SetTuple1(i++, std::sqrt(u*u + v*v)); + } + } + this->strength->Modified(); +} diff --git a/particle-track-and-trace/src/layers/EColLayer.h b/particle-track-and-trace/src/layers/EColLayer.h new file mode 100644 index 0000000..4934728 --- /dev/null +++ b/particle-track-and-trace/src/layers/EColLayer.h @@ -0,0 +1,46 @@ +#ifndef ECOLLAYER_H +#define ECOLLAYER_H + +#include "Layer.h" +#include +#include +#include +#include + +#include "../advection/UVGrid.h" + +/** Implements the Layer class for the case of a Eulerian visualization. + * Specifically, this class models the eulerian flow-fields of the simulation using the 'colourmap' mark and 'hue' channel to denote strength of velocities. + */ +class EColLayer : public Layer { +private: + vtkSmartPointer strength; + std::shared_ptr uvGrid; + int numLats; + int numLons; + + /** This private function sets up the initial coordinates for the glyphs in the dataset. + * It also reads some initial data to actually display. + */ + void readCoordinates(); + + + /** This private function builds up the lookup table VTK uses when determning what colour each cell ought to be. + */ + // TODO: implement this function. + void buildLut(); + +public: + /** Constructor. + */ + EColLayer(std::shared_ptr uvGrid); + + /** updates the map to reflect the given timestamp in the dataset. + * @param t : the time at which to fetch the data. + */ + void updateData(int t); + +}; + + +#endif diff --git a/particle-track-and-trace/src/main.cpp b/particle-track-and-trace/src/main.cpp index ee3f077..00cc38d 100644 --- a/particle-track-and-trace/src/main.cpp +++ b/particle-track-and-trace/src/main.cpp @@ -10,6 +10,7 @@ #include #include "layers/BackgroundImage.h" +#include "layers/EColLayer.h" #include "layers/EGlyphLayer.h" #include "layers/LGlyphLayer.h" #include "Program.h" @@ -35,7 +36,8 @@ int main() { unique_ptr program = make_unique(DT); program->addLayer(new BackgroundImage(dataPath + "/map_661-661.png")); - program->addLayer(new EGlyphLayer(uvGrid)); + // program->addLayer(new EGlyphLayer(uvGrid)); + program->addLayer(new EColLayer(uvGrid)); program->addLayer(l); program->render();