[vtkusers] Pb with writting images in separate thread
Peter KURNEV
p-kurnev at opencascade.com
Tue Nov 1 09:07:04 EST 2005
Hello.
I want to write the contents of my vtk window as a sequence of image
files in jpeg format.
The way I used is practically the same as it is implemented in the class
vtkVideoSource.
(some functions are taken straightforward from vtkVideoSource.cxx)
In order to solve the pb I created the separate thread (see class
Z_Recorder) with the thread
function FunctionRecord. This function contains the loop that invokes
the method
Z_Recorder::InternalGrab( ) with the frequency of 1 time/sec.
The function Z_Recorder::InternalGrab( ) just grabs the contents of the
window and wrtie it
to the file.
The process above starts at the moment when the cursor of the mouse
enters inside the
window (gStart=1;)
The platform is Linux Debian.
The code below is dfaft version. It uses globals and so on. Please do
not pay attention
on the style. It just implements the general idea
The program hungs and results on the console can be of different types:
1.
Segmentation fault
2.
X Error of failed request: BadAccess (attempt to access private
resource denied)
Major opcode of failed request: 145 (GLX)
Minor opcode of failed request: 5 (X_GLXMakeCurrent)
Serial number of failed request: 63
Current serial number in output stream: 63
3.
Xlib: unexpected async reply (sequence 0x39)!
I suspect that the pb is in synchronization but I do not know how to fix it.
Could you, please, help to fix the problem ?
Thanks in advance.
__________
Peter
#include<stdio.h>
#include <ctype.h>
#include <time.h>
//
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkCommand.h"
#include "vtkBoxWidget.h"
#include "vtkTransform.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include <vtkSphereSource.h>
#include <vtkImplicitPlaneWidget.h>
#include <vtkPlane.h>
#include <vtkClipPolyData.h>
#include <vtkLODActor.h>
#include <vtkProperty.h>
#include <vtkWindowToImageFilter.h>
#include <vtkJPEGWriter.h>
#include <vtkObjectFactory.h>
#include <vtkMultiThreader.h>
#include <vtkTimerLog.h>
#include <vtkCriticalSection.h>
#include <vtkObject.h>
#include <vtkMutexLock.h>
#include <ctype.h>
#include <time.h>
vtkJPEGWriter *gWriter=NULL;
vtkWindowToImageFilter *gWTIF=NULL;
vtkRenderWindow *gRenWin=NULL;
int gStart=0;
//====================================================================
//
static
void *FunctionRecord(vtkMultiThreader::ThreadInfo *data);
static
int FunctionThreadSleep(vtkMultiThreader::ThreadInfo *data,
double time);
static
void FunctionSleep(double duration);
//
//====================================================================
class Z_Recorder : public vtkObject
{
public:
static Z_Recorder *New();
vtkTypeRevisionMacro(Z_Recorder,vtkObject);
//
void Record();
void InternalGrab();
protected:
Z_Recorder();
~Z_Recorder();
protected:
int myRecording;
int myPlayerThreadId;
int myCounter;
vtkMultiThreader *myPlayerThreader;
private:
Z_Recorder(const Z_Recorder&); //Not implemented
void operator=(const Z_Recorder&); //Not implemented
};
// implementation
vtkCxxRevisionMacro(Z_Recorder,"$Revision$");
vtkStandardNewMacro(Z_Recorder);
//
//==================================================================
Z_Recorder::Z_Recorder()
{
myRecording=0;
myPlayerThreader=vtkMultiThreader::New();
myPlayerThreadId=0;
myCounter=0;
}
//==================================================================
Z_Recorder::~Z_Recorder()
{
myPlayerThreader->Delete();
}
//==================================================================
void Z_Recorder::Record()
{
if (!myRecording){
myRecording=1;
myPlayerThreadId=myPlayerThreader->
SpawnThread((vtkThreadFunctionType)&FunctionRecord,
this);
}
}
//==================================================================
void Z_Recorder::InternalGrab()
{
char buf[128];
//
sprintf(buf, "/data/pkv/IMAGES/TMP/abcx_%d.jpeg", myCounter);
//
gWriter->SetFileName(buf);
gWTIF->Modified();
gWriter->Write();
//
++myCounter;
}
//==================================================================
void FunctionSleep(double duration)
{
duration = duration;
#ifdef _WIN32
Sleep((int)(1000*duration));
#elif defined(__FreeBSD__) || defined(__linux__) || defined(sgi)
struct timespec sleep_time, dummy;
sleep_time.tv_sec = (int)duration;
sleep_time.tv_nsec = (int)(1000000000*(duration-sleep_time.tv_sec));
nanosleep(&sleep_time,&dummy);
#endif
}
//==================================================================
int FunctionThreadSleep(vtkMultiThreader::ThreadInfo *data,
double time)
{
int activeFlag, i;
double remaining;
//
while(1) {
remaining = time - vtkTimerLog::GetCurrentTime();
if (remaining <= 0) {
return 1;
}
if (remaining > 0.1) {
remaining = 0.1;
}
data->ActiveFlagLock->Lock();
activeFlag = *(data->ActiveFlag);
data->ActiveFlagLock->Unlock();
if (activeFlag==0) {
return 0;
}
FunctionSleep(remaining);
}
}
//====================================================================
void *FunctionRecord(vtkMultiThreader::ThreadInfo *data)
{
Z_Recorder *pSelf;
static int iX=0;
double startTime;
int iFrame, iFlag;
//
pSelf=(Z_Recorder *)(data->UserData);
iFrame=1;
while (1) {
if (!gStart){
continue;
}
else {
if (!iX){
startTime = vtkTimerLog::GetCurrentTime();
iX=1;
}
}
iFlag=FunctionThreadSleep(data, startTime+iFrame);
if (!iFlag){
break;
}
pSelf->InternalGrab();
iFrame++;
}
}
//====================================================================
class vtkMyCallback : public vtkCommand
{
public:
static vtkMyCallback *New() {
return new vtkMyCallback;
}
virtual void Execute(vtkObject *caller, unsigned long theEvent, void*)
{
if (theEvent==vtkCommand::MouseMoveEvent){
gStart=1;
}
}
};
//====================================================================
// function: main
// purpose:
//====================================================================
int main( int argc, char *argv[] )
{
vtkSphereSource *pSphereSource = vtkSphereSource::New();
pSphereSource->SetCenter(0., 0., 0.);
pSphereSource->SetRadius(1.);
pSphereSource->SetThetaResolution(30);
pSphereSource->SetPhiResolution(30);
vtkPolyDataMapper *pMapper = vtkPolyDataMapper::New();
pMapper->SetInput(pSphereSource->GetOutput());
vtkActor *pActor = vtkActor::New();
pActor->SetMapper( pMapper );
///
vtkRenderer *ren1= vtkRenderer::New();
vtkCamera *pCamera=ren1->GetActiveCamera();
pCamera->SetParallelProjection(1);
ren1->AddActor( pActor );
ren1->SetBackground(0., 0., 0.);
//
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer( ren1 );
renWin->SetSize( 300, 300 );
//
vtkWindowToImageFilter *pWTIF=vtkWindowToImageFilter::New();
pWTIF->SetInput(renWin);
vtkJPEGWriter *pWriter=vtkJPEGWriter::New();
pWriter->SetInput(pWTIF->GetOutput());
//
gRenWin=renWin;
gWTIF=pWTIF;
gWriter=pWriter;
//
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
//
vtkInteractorStyleTrackballCamera *style=
vtkInteractorStyleTrackballCamera::New();
//
iren->SetInteractorStyle(style);
//
vtkMyCallback *callback = vtkMyCallback::New();
iren->AddObserver(vtkCommand::MouseMoveEvent, callback);
//
Z_Recorder *pRecorder=Z_Recorder::New();
pRecorder->Record();
//
iren->Initialize();
iren->Start();
//
pSphereSource->Delete();
pMapper->Delete();
pActor->Delete();
//...
return 0;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p-kurnev.vcf
Type: text/x-vcard
Size: 301 bytes
Desc: not available
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20051101/ba0f8c92/attachment.vcf>
More information about the vtkusers
mailing list