<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style id="owaParaStyle" type="text/css">
<!--
p
{margin-top:0;
margin-bottom:0}
p
{margin-top:0;
margin-bottom:0}
-->
P {margin-top:0;margin-bottom:0;}</style>
</head>
<body ocsi="0" fpstyle="1">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">In case anyone is interested, I found the simple solution.<br>
<br>
renderer->RemoveActor(actor);<br>
renderer->AddActor(actor);<br>
<br>
:)<br>
<br>
<div style="font-family: Times New Roman; color: #000000; font-size: 16px">
<hr tabindex="-1">
<div style="direction: ltr;" id="divRpF757916"><font color="#000000" face="Tahoma" size="2"><b>From:</b> vtkusers [vtkusers-bounces@vtk.org] on behalf of Gib Bogle [g.bogle@auckland.ac.nz]<br>
<b>Sent:</b> Saturday, 26 July 2014 12:29 p.m.<br>
<b>To:</b> vtkusers@vtk.org<br>
<b>Subject:</b> Re: [vtkusers] Animation problem<br>
</font><br>
</div>
<div></div>
<div>
<div style="direction:ltr; font-family:Tahoma; color:#000000; font-size:10pt">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.)<br>
<br>
// This creates the first shape (straight)<br>
MakeTube(nd, nstrips, dtheta1, points, strips);<br>
polydata->SetPoints(points);<br>
polydata->SetStrips(strips);<br>
<br>
// Create an actor and mapper<br>
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();<br>
mapper->SetInput(polydata);<br>
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();<br>
actor->SetMapper(mapper);<br>
renderer->AddActor(actor);<br>
renderWindow->Render(); // <<< remove this and the second shape is rendered<br>
<br>
// This creates the second shape (curved)<br>
strips->Initialize();<br>
MakeTube(nd, nstrips, dtheta2, points, strips);<br>
renderWindow->Render();<br>
<br>
renderWindowInteractor->Start();<br>
<br>
<div style="font-family:Times New Roman; color:#000000; font-size:16px">
<hr tabindex="-1">
<div id="divRpF273361" style="direction:ltr"><font color="#000000" face="Tahoma" size="2"><b>From:</b> vtkusers [vtkusers-bounces@vtk.org] on behalf of Gib Bogle [g.bogle@auckland.ac.nz]<br>
<b>Sent:</b> Friday, 25 July 2014 5:58 p.m.<br>
<b>To:</b> vtkusers@vtk.org<br>
<b>Subject:</b> [vtkusers] Animation problem<br>
</font><br>
</div>
<div></div>
<div>
<div style="direction:ltr; font-family:Tahoma; color:#000000; font-size:10pt">Hi,<br>
I'm trying to implement an animation program, basing it closely (I think) on this example:<br>
<a href="http://www.vtk.org/Wiki/VTK/Examples/Cxx/Utilities/Animation" target="_blank">http://www.vtk.org/Wiki/VTK/Examples/Cxx/Utilities/Animation</a><br>
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:<br>
<br>
strips->Initialize();<br>
MakeTube(nd, nstrips, dtheta, points, strips);<br>
polydata->Reset();<br>
polydata->SetPoints(points);<br>
polydata->SetStrips(strips);<br>
mapper->RemoveAllInputs();<br>
mapper->SetInput(polydata);<br>
actor->SetMapper(mapper);<br>
mapper->Update();<br>
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::SafeDownCast(caller);<br>
iren->GetRenderWindow()->Render();<br>
<br>
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...<br>
<br>
class vtkTimerCallback2 : public vtkCommand<br>
{<br>
public:<br>
static vtkTimerCallback2 *New()<br>
{<br>
vtkTimerCallback2 *cb = new vtkTimerCallback2;<br>
cb->TimerCount = 0;<br>
return cb;<br>
}<br>
<br>
virtual void Execute(vtkObject *caller, unsigned long eventId, void * vtkNotUsed(callData))<br>
{<br>
if (vtkCommand::TimerEvent == eventId)<br>
{<br>
++this->TimerCount;<br>
}<br>
std::cout << this->TimerCount << std::endl;<br>
// actor->SetPosition(this->TimerCount/10., this->TimerCount/10.,0.);<br>
<br>
dtheta = new double[nstrips];<br>
for (int i=0; i<nstrips; i++) {<br>
dtheta[i] = 0.0;<br>
}<br>
strips->Initialize();<br>
MakeTube(nd, nstrips, dtheta, points, strips);<br>
polydata->Reset();<br>
polydata->SetPoints(points);<br>
polydata->SetStrips(strips);<br>
mapper->RemoveAllInputs();<br>
mapper->SetInput(polydata);<br>
actor->SetMapper(mapper);<br>
mapper->Update();<br>
<br>
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::SafeDownCast(caller);<br>
iren->GetRenderWindow()->Render();<br>
}<br>
<br>
private:<br>
int TimerCount;<br>
double *dtheta;<br>
public:<br>
int nd;<br>
int nstrips;<br>
vtkPolyData *polydata;<br>
vtkCellArray *strips;<br>
vtkPoints *points;<br>
vtkDataSetMapper *mapper;<br>
vtkActor* actor;<br>
};<br>
<br>
<br>
int main(int argc, char *argv[])<br>
{<br>
int nd = 20;<br>
int nstrips = 4;<br>
double *dtheta;<br>
<br>
PI = 4*atan(1.0);<br>
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();<br>
vtkSmartPointer<vtkCellArray> strips = vtkSmartPointer<vtkCellArray>::New();<br>
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); // we want just one big array of points<br>
points->SetNumberOfPoints(nd*(nstrips+1)); <br>
strips->SetNumberOfCells(nstrips);<br>
<br>
dtheta = new double[nstrips];<br>
dthetafinal = new double[nstrips];<br>
for (int i=0; i<nstrips; i++) {<br>
dtheta[i] = 0.1;<br>
dthetafinal[i] = 0.1;<br>
}<br>
<br>
MakeTube(nd, nstrips, dtheta, points, strips);<br>
polydata->SetPoints(points);<br>
polydata->SetStrips(strips);<br>
<br>
// Create an actor and mapper<br>
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();<br>
#if VTK_MAJOR_VERSION <= 5<br>
mapper->SetInput(polydata);<br>
#else<br>
mapper->SetInputData(polydata);<br>
#endif<br>
<br>
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();<br>
actor->SetMapper(mapper);<br>
<br>
// Create a renderer, render window, and interactor<br>
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();<br>
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();<br>
renderWindow->AddRenderer(renderer);<br>
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();<br>
renderWindowInteractor->SetRenderWindow(renderWindow);<br>
<br>
renderer->AddActor(actor);<br>
renderWindow->Render();<br>
<br>
// Initialize must be called prior to creating timer events.<br>
renderWindowInteractor->Initialize();<br>
<br>
// Sign up to receive TimerEvent<br>
vtkSmartPointer<vtkTimerCallback2> cb = vtkSmartPointer<vtkTimerCallback2>::New();<br>
cb->actor = actor;<br>
cb->nd = nd;<br>
cb->nstrips = nstrips;<br>
cb->points = points;<br>
cb->strips = strips;<br>
cb->polydata = polydata;<br>
cb->mapper = mapper;<br>
renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, cb);<br>
<br>
int timerId = renderWindowInteractor->CreateRepeatingTimer(1000);<br>
std::cout << "timerId: " << timerId << std::endl;<br>
<br>
renderWindowInteractor->Start();<br>
<br>
return EXIT_SUCCESS;<br>
}<br>
<br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>