#include "EGlyphLayer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../CartographicTransformation.h" using namespace netCDF; using namespace std; template vector getVarVector(const NcVar &var) { int length = 1; for (NcDim dim : var.getDims()) { length *= dim.getSize(); } vector vec(length); var.getVar(vec.data()); return vec; } tuple, vector, vector> readGrid() { netCDF::NcFile data("../../../../data/grid.h5", netCDF::NcFile::read); multimap< string, NcVar > vars = data.getVars(); vector time = getVarVector(vars.find("times")->second); vector longitude = getVarVector(vars.find("longitude")->second); vector latitude = getVarVector(vars.find("latitude")->second); return {time, latitude, longitude}; } EGlyphLayer::EGlyphLayer() { this->ren = vtkSmartPointer::New(); this->ren->SetLayer(1); this->ren->InteractiveOff(); this->data = vtkSmartPointer::New(); this->direction = vtkSmartPointer::New(); this->direction->SetName("direction"); readCoordinates(); } void EGlyphLayer::readCoordinates() { vtkNew points; auto [times, lats, lons] = readGrid(); // FIXME: import Robin's readData function and use it this->numLats = lats.size(); this->numLons = lons.size(); this->direction->SetNumberOfComponents(3); this->direction->SetNumberOfTuples(numLats*numLons); points->Allocate(numLats*numLons); auto camera = createNormalisedCamera(); ren->SetActiveCamera(camera); int i = 0; for (double lat : lats) { for (double lon : lons) { cout << "lon: " << lon << " lat: " << lat << endl; direction->SetTuple3(i, 0.45, 0.90, 0); //FIXME: read this info from file points->InsertPoint(i++, lon, lat, 0); // see also https://vtk.org/doc/nightly/html/classvtkPolyDataMapper2D.html } } this->data->SetPoints(points); this->data->GetPointData()->AddArray(this->direction); this->data->GetPointData()->SetActiveVectors("direction"); vtkSmartPointer transformFilter = createCartographicTransformFilter(); 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 coordinate; // coordinate->SetCoordinateSystemToWorld(); vtkNew(mapper); // mapper->SetTransformCoordinate(coordinate); 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) { 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(); }