Mercurial > hg > kwantix
view src/vtkplot.cpp @ 43:8aea477c7cf8
Continue implementation of vtkplot class, only missing to move the tail of the pipeline to the Plot function.
author | Jordi Gutiérrez Hermoso <jordigh@gmail.com> |
---|---|
date | Mon, 15 Mar 2010 21:10:18 -0600 (2010-03-16) |
parents | 3f8311cbf602 |
children | 4134a0f2423d |
line wrap: on
line source
#include "include/vtkplot.hpp" #include <vtkPoints.h> #include <vtkPointData.h> #include <vtkDelaunay2D.h> #include <vtkLookupTable.h> #include <vtkPolyData.h> #include <vtkPolyDataNormals.h> #include <vtkPolyDataMapper.h> #include <vtkWarpScalar.h> #include <vtkCamera.h> #include <vtkActor.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> #include <vtkInteractorStyleTerrain.h> #include <vtkSmartPointer.h> #include <vtkDoubleArray.h> #include <vtkGraphicsFactory.h> #include <vtkImagingFactory.h> #include <vtkWindowToImageFilter.h> #include <vtkPNGWriter.h> #include <vtkSmartPointer.h> #include <vtkObjectFactory.h> #include <vtkSphereSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderWindow.h> #include <vtkRenderer.h> #include <vtkRenderWindowInteractor.h> #include <vtkProgrammableFilter.h> #include <vtkCommand.h> #include <vtkCamera.h> #include <string> #include <sstream> #include <iomanip> #include <boost/function.hpp> namespace kwantix{ template<typename RBF> vtkplot::vtkplot(const interpolator<RBF>& u, bool offscreen_in) :hash(u.rbfs_hash), offscreen(offscreen) { if(u.thebvp -> get_domain() -> get_dimension() != 2) { badArgument exc; exc.reason = "Class vtkplot only works on interpolators whose " "domain lies in R^2"; exc.line = __LINE__; exc.file = __FILE__; throw exc; } SetupPipeline(u, offscreen); } void vtkplot::set_offscreen(bool offscreen_in) { offscreen = offscreen_in; InitOffscreen(); } template<typename RBF> void vtkplot::update_values(const interp_values& vals_in) { vals = vals_in; programmableFilter -> Modified(); } void vtkplot::trampoline(void* this_ptr) { vtkplot* instance = static_cast<vtkplot*>(this_ptr); instance -> AdjustPoints(); } template<typename RBF> void vtkplot::SetupPipeline(const interpolator<RBF>& u) { vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkDoubleArray> scalars = vtkSmartPointer<vtkDoubleArray>::New(); for(auto i = u.thebvp -> get_domain() -> get_interior().begin(); i != u.thebvp -> get_domain() -> get_interior().end(); i++) { double z = 0; vtkIdType idx = points -> InsertNextPoint( *i(1), *i(2), 0); scalars -> InsertTuple(idx, &z); } for(auto i = u.thebvp -> get_domain() -> get_boundary().begin(); i != u.thebvp -> get_domain() -> get_boundary().end(); i++) { double z = 0; vtkIdType idx = points -> InsertNextPoint( *i(1), *i(2), 0); scalars -> InsertTuple(idx, &z); } //add the grid points to a polydata object vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(points); polydata->GetPointData() -> SetScalars(scalars); //triangulate the grid points vtkSmartPointer<vtkDelaunay2D> delaunay = vtkSmartPointer<vtkDelaunay2D>::New(); delaunay->SetInput(polydata); delaunay->Update(); InitOffscreen(); programmableFilter = vtkSmartPointer<vtkProgrammableFilter>::New(); programmableFilter->SetInput(delaunay -> GetOutput()); programmableFilter->SetExecuteMethod(trampoline, this); //Normals for Gourad shading vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New(); normals -> SetInputConnection(programmableFilter -> GetOutputPort() ); normals -> SetFeatureAngle(60); //Set the colours for the rendering vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New(); lut -> SetHueRange(0.66667, 0.0); lut -> SetNumberOfColors(256); lut -> SetRampToLinear(); lut -> Build(); // map the contours to graphical primitives vtkSmartPointer<vtkPolyDataMapper> contMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); contMapper->SetInput(normals -> GetOutput() ); contMapper->SetScalarRange(0,1); contMapper->SetLookupTable(lut); contMapper->ImmediateModeRenderingOn(); // create an actor for the contours vtkSmartPointer<vtkActor> contActor = vtkSmartPointer<vtkActor>::New(); contActor->SetMapper(contMapper); // a renderer and render window ren1 = vtkSmartPointer<vtkRenderer>::New(); renWin = vtkSmartPointer<vtkRenderWindow>::New(); if(offscreen) { renWin->SetOffScreenRendering(1); } renWin->AddRenderer(ren1); // an interactor vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New(); iren->SetRenderWindow(renWin); // Initialize must be called prior to creating timer events. iren->Initialize(); iren->CreateRepeatingTimer(10); // add the actors to the scene ren1->SetBackground(0.0,0.0,0.0); ren1->GetActiveCamera()->SetViewUp(0,0,1); ren1->GetActiveCamera()->SetPosition(1, 1, 1); ren1->GetActiveCamera()->SetParallelProjection(1); ren1->AddActor(contActor); ren1->ResetCamera(); if(offscreen) { for(size_t i = 0; i < 1000; i++) { using namespace std; string filename = "foo"; stringstream ss; string i_str; ss << setw(4) << setfill('0') << i; ss >> i_str; filename += i_str + ".png"; // Write to file vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New(); windowToImageFilter->SetInput(renWin); windowToImageFilter->Update(); vtkSmartPointer<vtkPNGWriter> writer = vtkSmartPointer<vtkPNGWriter>::New(); writer->SetFileName(filename.c_str() ); writer->SetInput(windowToImageFilter->GetOutput()); writer->Write(); programmableFilter -> Modified(); } } else { // render an image (lights and cameras are created automatically) renWin->Render(); //The style vtkSmartPointer<vtkInteractorStyleTerrain> terrain_style = vtkSmartPointer<vtkInteractorStyleTerrain>::New(); // Set the style iren -> SetInteractorStyle(terrain_style); // begin mouse interaction iren->Start(); } } void vtkplot::InitOffscreen() { // Graphics Factory vtkSmartPointer<vtkGraphicsFactory> graphics_factory = vtkSmartPointer<vtkGraphicsFactory>::New(); graphics_factory->SetOffScreenOnlyMode( offscreen ); graphics_factory->SetUseMesaClasses( offscreen ); // Imaging Factory vtkSmartPointer<vtkImagingFactory> imaging_factory = vtkSmartPointer<vtkImagingFactory>::New(); imaging_factory->SetUseMesaClasses( offscreen ); } void vtkplot::AdjustPoints() { if(vals.get_hash() != hash) { badArgument exc; exc.reason = "Can't update vtkplot with data from a different " "interpolation domain."; exc.line = __LINE__; exc.file = __FILE__; throw exc; } vtkPoints* inPts = programmableFilter->GetPolyDataInput()->GetPoints(); vtkIdType numPts = inPts->GetNumberOfPoints(); vtkSmartPointer<vtkPoints> newPts = vtkSmartPointer<vtkPoints>::New(); newPts->SetNumberOfPoints(numPts); vtkSmartPointer<vtkDoubleArray> newScalars = vtkSmartPointer<vtkDoubleArray>::New(); for(vtkIdType i = 0; i < numPts; i++) { double p[3]; inPts -> GetPoint(i,p); p[2] = vals(i+1); newPts -> SetPoint(i,p); newScalars -> InsertTuple(i, &p[2]); } programmableFilter-> GetPolyDataOutput()->CopyStructure(programmableFilter->GetPolyDataInput()); programmableFilter->GetPolyDataOutput()->SetPoints(newPts); programmableFilter ->GetPolyDataOutput() ->GetPointData() -> SetScalars(newScalars); } } //namespace kwantix