[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