#include "EGlyphLayer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../CartographicTransformation.h" #include "../advection/readdata.h" #include "../advection/interpolate.h" using namespace std; EGlyphLayer::EGlyphLayer(std::shared_ptr uvGrid) { this->ren = vtkSmartPointer::New(); this->ren->SetLayer(1); this->ren->InteractiveOff(); this->uvGrid = uvGrid; this->data = vtkSmartPointer::New(); this->direction = vtkSmartPointer::New(); this->direction->SetName("direction"); readCoordinates(); } void EGlyphLayer::readCoordinates() { vtkNew points; this->numLats = uvGrid->lats.size(); this->numLons = uvGrid->lons.size(); this->direction->SetNumberOfComponents(3); this->direction->SetNumberOfTuples(numLats * numLons); points->Allocate(numLats * numLons); int i = 0; int latIndex = 0; for (double lat: uvGrid->lats) { int lonIndex = 0; for (double lon: uvGrid->lons) { auto [u, v] = (*uvGrid)[0, latIndex, lonIndex]; direction->SetTuple3(i, 5*u, 5*v, 0); points->InsertPoint(i++, lon, lat, 0); lonIndex++; } latIndex++; } this->data->SetPoints(points); this->data->GetPointData()->AddArray(this->direction); this->data->GetPointData()->SetActiveVectors("direction"); vtkSmartPointer transformFilter = createCartographicTransformFilter(uvGrid); transformFilter->SetInputData(data); vtkNew arrowSource; arrowSource->SetGlyphTypeToArrow(); arrowSource->SetScale(0.2); //TODO: set this properly arrowSource->Update(); vtkNew glyph2D; glyph2D->SetSourceConnection(arrowSource->GetOutputPort()); glyph2D->SetInputConnection(transformFilter->GetOutputPort()); glyph2D->OrientOn(); glyph2D->ClampingOn(); glyph2D->SetScaleModeToScaleByVector(); glyph2D->SetVectorModeToUseVector(); glyph2D->Update(); vtkNew(mapper); mapper->SetInputConnection(glyph2D->GetOutputPort()); mapper->Update(); vtkNew actor; actor->SetMapper(mapper); actor->GetProperty()->SetColor(0, 0, 0); actor->GetProperty()->SetOpacity(0.2); this->ren->AddActor(actor); } void EGlyphLayer::updateData(int t) { int i = 0; for (int lat = 0; lat < uvGrid->latSize; lat++) { for (int lon = 0; lon < uvGrid->lonSize; lon++) { auto [u, v] = (*uvGrid)[t/3600, lat, lon]; // TODO: 5*v scaling stuff should really be a filter transform this->direction->SetTuple3(i, 5*u, 5*v, 0); i++; } } this->direction->Modified(); }