changeset 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
parents 3f8311cbf602
children 4134a0f2423d
files src/include/interp_values.hpp src/include/vtkplot.hpp src/interp_values.cpp src/vtkplot.cpp
diffstat 4 files changed, 115 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/src/include/interp_values.hpp
+++ b/src/include/interp_values.hpp
@@ -85,6 +85,11 @@
   friend interp_values operator/(double a, const interp_values& v); 
   //@}
 
+  /// Return value at ith position
+  double operator()(size_t i) const;
+  /// Get the hash for this set of values
+  size_t get_hash() const;
+
 protected:
   /// Interpolator creates interp_values with this
   interp_values(const kwantix::vector& v_in, size_t rbfs_hash_in,
--- a/src/include/vtkplot.hpp
+++ b/src/include/vtkplot.hpp
@@ -1,10 +1,12 @@
-
 #ifndef __VTKPLOTTING_HPP__
 #define __VTKPLOTTING_HPP__
 
 #include <string>
 
 #include <vtkSmartPointer.h>
+#include <vtkProgrammableFilter.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderer.h>
 
 #include "interpolator.hpp"
 namespace kwantix{
@@ -22,35 +24,50 @@
   vtkplot(const interpolator<RBF>& u, 
           bool offscreen_in = false);
   ///Defines the view direction when plotting.
-  void set_view_direction(const vector& dir);
+  void set_view_direction(double x, double y, double z);
   ///Without changing the triangulation, update the values.
   template<typename RBF>
-  void update_values(const interpolator<RBF>& u);
+  void update_values(const interp_values& vals_in);
   ///Enable offscreen plotting.
-  void plot_offscreen(bool offscreen = true);
+  void set_offscreen(bool offscreen_in = true);
   ///Set the base filename used for saving, to which numbers are appended.
   void set_base_filename(const std::string& basename);
   ///Actually do the plot, whether offscreen or onscreen.
   void plot() const;
 
+  ///The VTK callback for updating the surface points
+  void AdjustPoints();
+  ///Trampoline function for VTK callback
+  static void trampoline(void* this_ptr);
+
 private:
   
   ///Setup the initial pipeline
   template<typename RBF>
   void SetupPipeline(const interpolator<RBF>& u);
   
+  ///A VTK callback to insert in the pipeline to modify an existing plotting pipeline
+  vtkSmartPointer<vtkProgrammableFilter> programmableFilter;
+
   ///Setup the pipeline to plot offscreen or not
   void InitOffscreen();
 
-  template<typename RBF>
-  static void AdjustPoints(void* arguments);
+  ///Values with which to update the surface data
+  interp_values& vals;
+
+  /*! \name VTK pipeline endpoints
+   *
+   * Endpoint
+   */
+  //@{
+  vtkSmartPointer<vtkRenderer> ren1;
+	vtkSmartPointer<vtkRenderWindow> renWin;
+  //@}
 
   ///The associated interpolator's hash
   size_t hash;
   ///Base filename
   string basename;
-  ///Direction from which to plot
-  vector view_direction;
   ///Whether to plot offscreen or not
   bool offscreen;
 };
--- a/src/interp_values.cpp
+++ b/src/interp_values.cpp
@@ -15,6 +15,18 @@
   return exc;
 }
 
+double 
+interp_values::operator()(size_t i) const
+{
+  return v(i);
+}
+
+size_t 
+interp_values::get_hash() const
+{
+  return rbfs_hash;
+}
+
 interp_values 
 interp_values::operator+(const interp_values& w) const
 {
--- a/src/vtkplot.cpp
+++ b/src/vtkplot.cpp
@@ -44,73 +44,9 @@
 #include <sstream>
 #include <iomanip> 
 
-namespace kwantix{
-
-class CommandSubclass : public vtkCommand
-{
-public:
-  static CommandSubclass *New()
-  {
-    return new CommandSubclass;
-  }
- 
-  void Execute(vtkObject *caller, unsigned long eventId, 
-               void *callData)
-  {
-    vtkRenderWindowInteractor *iren = 
-      static_cast<vtkRenderWindowInteractor*>(caller);
- 
-    this->ProgrammableFilter->Modified();
- 
-    iren->Render();
- 
-  }
- 
-  vtkSmartPointer<vtkProgrammableFilter> ProgrammableFilter;
- 
-};
+#include <boost/function.hpp>
 
-template<typename RBF>
-void vtkplot::AdjustPoints(void* arguments)
-{
-  vtkProgrammableFilter* programmableFilter = 
-    static_cast<vtkProgrammableFilter*>(arguments);
-  arguments = programmableFilter + 1;
-  
-  auto u = static_cast< const interpolator<RBF>& > (arguments);
-  
-  vtkPoints* inPts = programmableFilter->GetPolyDataInput()->GetPoints();
-  vtkIdType numPts = inPts->GetNumberOfPoints();
-  vtkSmartPointer<vtkPoints> newPts =
-    vtkSmartPointer<vtkPoints>::New();
-  newPts->SetNumberOfPoints(numPts);
- 
-  vtkSmartPointer<vtkDoubleArray> newScalars 
-    = vtkSmartPointer<vtkDoubleArray>::New();
-
-  static double t = 0;
-
-  //auto& vals = u.at();
-
-  for(vtkIdType i = 0; i < numPts; i++)
-  {
-    double p[3];
-    inPts -> GetPoint(i,p);
-    //p[2] = F(p[0],p[1],t);
-    newPts -> SetPoint(i,p);
-    newScalars -> InsertTuple(i, &p[2]);
-	}
-
-  t += 0.05;
- 
-  programmableFilter->
-    GetPolyDataOutput()->CopyStructure(programmableFilter->GetPolyDataInput());
-
-  programmableFilter->GetPolyDataOutput()->SetPoints(newPts);
-  programmableFilter
-    ->GetPolyDataOutput()
-    ->GetPointData() -> SetScalars(newScalars);
-}
+namespace kwantix{
 
 template<typename RBF>
 vtkplot::vtkplot(const interpolator<RBF>& u, 
@@ -120,14 +56,36 @@
   if(u.thebvp -> get_domain() -> get_dimension() != 2)
   {
     badArgument exc;
-    exc.reason = "This class only works on interpolators whose domain lies in R^2";
+    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)
 {
@@ -163,11 +121,9 @@
 
   InitOffscreen();
 
-  vtkSmartPointer<vtkProgrammableFilter> programmableFilter = 
-    vtkSmartPointer<vtkProgrammableFilter>::New();
+  programmableFilter = vtkSmartPointer<vtkProgrammableFilter>::New();
   programmableFilter->SetInput(delaunay -> GetOutput());
-  programmableFilter->SetExecuteMethod(AdjustPoints<RBF>, programmableFilter, u);
-
+  programmableFilter->SetExecuteMethod(trampoline, this);
 
   //Normals for Gourad shading
   vtkSmartPointer<vtkPolyDataNormals> normals 
@@ -199,10 +155,8 @@
 	contActor->SetMapper(contMapper);
  
   // a renderer and render window
-	vtkSmartPointer<vtkRenderer> ren1 =
-    vtkSmartPointer<vtkRenderer>::New();
-	vtkSmartPointer<vtkRenderWindow> renWin 
-    = vtkSmartPointer<vtkRenderWindow>::New();
+	ren1 =  vtkSmartPointer<vtkRenderer>::New();
+	renWin = vtkSmartPointer<vtkRenderWindow>::New();
   if(offscreen)
   {
     renWin->SetOffScreenRendering(1);
@@ -218,23 +172,14 @@
   iren->Initialize();
   iren->CreateRepeatingTimer(10);
  
-  vtkSmartPointer<CommandSubclass> timerCallback = 
-    vtkSmartPointer<CommandSubclass>::New();
-  timerCallback->ProgrammableFilter = programmableFilter;
- 
-  iren->AddObserver ( vtkCommand::TimerEvent, timerCallback );
-
 	// add the actors to the scene
 	ren1->SetBackground(0.0,0.0,0.0);
   ren1->GetActiveCamera()->SetViewUp(0,0,1);
-  ren1->GetActiveCamera()->SetPosition(1, 0, 1);
+  ren1->GetActiveCamera()->SetPosition(1, 1, 1);
   ren1->GetActiveCamera()->SetParallelProjection(1);
 	ren1->AddActor(contActor);
   ren1->ResetCamera();
  
-  // render an image (lights and cameras are created automatically)
-	renWin->Render();
-
   if(offscreen)
   {
     for(size_t i = 0; i < 1000; i++)
@@ -263,6 +208,9 @@
   }
   else
   {
+
+    // render an image (lights and cameras are created automatically)
+    renWin->Render();
     //The style
     vtkSmartPointer<vtkInteractorStyleTerrain> terrain_style 
       = vtkSmartPointer<vtkInteractorStyleTerrain>::New();
@@ -273,7 +221,6 @@
     // begin mouse interaction
     iren->Start(); 
   }
-  return delaunay;
 }
 
 void vtkplot::InitOffscreen()
@@ -290,6 +237,46 @@
   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