[vtkusers] Animation problem

Gib Bogle g.bogle at auckland.ac.nz
Fri Jul 25 20:29:47 EDT 2014


I have narrowed down my problem somewhat, and discovered that it is not strictly related to the time callback.  The following code fragment illustrates the point.  I create a shape in polydata and render it, then change the shape and try to render it again.  With this code I see only the first shape.  If I comment out the first renderWindow->Render() then I see the second shape.  Using the timer callback does effectively what this code does, successively modifying and re-rendering the shape, i.e. repeating the three lines of code concerning the second shape.  What do I need to do to ensure that both renders have effect?  (Of course with this piece of code I will not see the first render unless I insert a delay.)

    // This creates the first shape (straight)
    MakeTube(nd, nstrips, dtheta1, points, strips);
    polydata->SetPoints(points);
    polydata->SetStrips(strips);

  // Create an actor and mapper
    vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
    mapper->SetInput(polydata);
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    renderer->AddActor(actor);
    renderWindow->Render();        // <<< remove this and the second shape is rendered

    // This creates the second shape (curved)
    strips->Initialize();
    MakeTube(nd, nstrips, dtheta2, points, strips);
    renderWindow->Render();

    renderWindowInteractor->Start();

________________________________
From: vtkusers [vtkusers-bounces at vtk.org] on behalf of Gib Bogle [g.bogle at auckland.ac.nz]
Sent: Friday, 25 July 2014 5:58 p.m.
To: vtkusers at vtk.org
Subject: [vtkusers] Animation problem

Hi,
I'm trying to implement an animation program, basing it closely (I think) on this example:
http://www.vtk.org/Wiki/VTK/Examples/Cxx/Utilities/Animation
Apparently I'm missing something because my program renders my actor correctly in the main program, but the code in the timer callback does not change what is being rendered.  The main program and the callback function are shown below.  The relevant part of the callback code that does not lead to a modified actor being rendered is this:

      strips->Initialize();
      MakeTube(nd, nstrips, dtheta, points, strips);
      polydata->Reset();
      polydata->SetPoints(points);
      polydata->SetStrips(strips);
      mapper->RemoveAllInputs();
      mapper->SetInput(polydata);
      actor->SetMapper(mapper);
      mapper->Update();
      vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::SafeDownCast(caller);
      iren->GetRenderWindow()->Render();

As you can see, I have been flailing around, trying various likely possibilities, revealing my obvious lack of understanding.  Initially I thought it would be sufficient to just change 'points' and 'strips', then I thought I should repopulate polydata, then...

class vtkTimerCallback2 : public vtkCommand
{
  public:
    static vtkTimerCallback2 *New()
    {
      vtkTimerCallback2 *cb = new vtkTimerCallback2;
      cb->TimerCount = 0;
      return cb;
    }

    virtual void Execute(vtkObject *caller, unsigned long eventId, void * vtkNotUsed(callData))
    {
      if (vtkCommand::TimerEvent == eventId)
        {
        ++this->TimerCount;
        }
      std::cout << this->TimerCount << std::endl;
//      actor->SetPosition(this->TimerCount/10., this->TimerCount/10.,0.);

      dtheta = new double[nstrips];
      for (int i=0; i<nstrips; i++) {
          dtheta[i] = 0.0;
      }
      strips->Initialize();
      MakeTube(nd, nstrips, dtheta, points, strips);
      polydata->Reset();
      polydata->SetPoints(points);
      polydata->SetStrips(strips);
      mapper->RemoveAllInputs();
      mapper->SetInput(polydata);
      actor->SetMapper(mapper);
      mapper->Update();

      vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::SafeDownCast(caller);
      iren->GetRenderWindow()->Render();
    }

  private:
    int TimerCount;
    double *dtheta;
  public:
    int nd;
    int nstrips;
    vtkPolyData *polydata;
    vtkCellArray *strips;
    vtkPoints *points;
    vtkDataSetMapper *mapper;
    vtkActor* actor;
};


int main(int argc, char *argv[])
{
    int nd = 20;
    int nstrips = 4;
    double *dtheta;

    PI = 4*atan(1.0);
    vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
    vtkSmartPointer<vtkCellArray> strips = vtkSmartPointer<vtkCellArray>::New();
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();    // we want just one big array of points
    points->SetNumberOfPoints(nd*(nstrips+1));
    strips->SetNumberOfCells(nstrips);

    dtheta = new double[nstrips];
    dthetafinal = new double[nstrips];
    for (int i=0; i<nstrips; i++) {
        dtheta[i] = 0.1;
        dthetafinal[i] = 0.1;
    }

    MakeTube(nd, nstrips, dtheta, points, strips);
    polydata->SetPoints(points);
    polydata->SetStrips(strips);

  // Create an actor and mapper
  vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  mapper->SetInput(polydata);
#else
  mapper->SetInputData(polydata);
#endif

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  // Create a renderer, render window, and interactor
  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderWindow->Render();

  // Initialize must be called prior to creating timer events.
  renderWindowInteractor->Initialize();

  // Sign up to receive TimerEvent
  vtkSmartPointer<vtkTimerCallback2> cb = vtkSmartPointer<vtkTimerCallback2>::New();
  cb->actor = actor;
  cb->nd = nd;
  cb->nstrips = nstrips;
  cb->points = points;
  cb->strips = strips;
  cb->polydata = polydata;
  cb->mapper = mapper;
  renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, cb);

  int timerId = renderWindowInteractor->CreateRepeatingTimer(1000);
  std::cout << "timerId: " << timerId << std::endl;

  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20140726/ea33f0b7/attachment-0001.html>


More information about the vtkusers mailing list