<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkFFMPEGWriter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkFFMPEGWriter.h"

#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#include "vtkErrorCode.h"

extern "C" {
#include <ffmpeg/avformat.h>
}

//---------------------------------------------------------------------------
class vtkFFMPEGWriterInternal
{
public:
  vtkFFMPEGWriterInternal(vtkFFMPEGWriter *creator);
  ~vtkFFMPEGWriterInternal();

  int Start();
  int Write(vtkImageData *id);
  void End();

  int Dim[2];
  int FrameRate;

private:

  vtkFFMPEGWriter *Writer;

  AVFormatContext *avFormatContext;

  AVOutputFormat *avOutputFormat;

  AVStream *avStream;

  unsigned char *codecBuf;
  int codecBufSize;

  AVFrame *rgbInput;
  AVFrame *yuvOutput;

  int openedFile;
  int closedFile;
};

//---------------------------------------------------------------------------
vtkFFMPEGWriterInternal::vtkFFMPEGWriterInternal(vtkFFMPEGWriter *creator)
{
  this->Writer = creator;
  this->Dim[0] = 0;
  this->Dim[1] = 0;

  this->avFormatContext = NULL;

  this->avOutputFormat = NULL;

  this->avStream = NULL;

  this->codecBuf = NULL;
  this->rgbInput = NULL;
  this->yuvOutput = NULL;

  this->openedFile = 0;
  this->closedFile = 1;

  this->FrameRate = 25;
}

//---------------------------------------------------------------------------
vtkFFMPEGWriterInternal::~vtkFFMPEGWriterInternal()
{
  if (!this->closedFile)
    {
    this->End();
    }
}

//---------------------------------------------------------------------------
int vtkFFMPEGWriterInternal::Start()
{
  this->closedFile = 0;

  //initialize libavcodec, and register all codecs and formats
  av_register_all();

  //create the format context that wraps all of the media output structures
  this->avFormatContext = av_alloc_format_context();
  if (!this->avFormatContext)
    {
    vtkErrorMacro( "Could not open the format context." );
    return 0;
    }

  //choose avi media file format
  this->avOutputFormat = guess_format("avi", NULL, NULL);
  if (!this->avOutputFormat)
    {
    vtkErrorMacro( "Could not open the avi media file format." );
    return 0;
    }

  //choose a codec that is easily playable on windows
  this->avOutputFormat->video_codec = CODEC_ID_MSMPEG4V3;

  //assign the format to the context
  this->avFormatContext->oformat = this->avOutputFormat;

  //choose a filename for the output
  strcpy(this->avFormatContext->filename, this->Writer->GetFileName());

  //create a stream for that file
  this->avStream = av_new_stream(this->avFormatContext, 0);
  if (!this->avStream)
    {
    vtkErrorMacro( "Could not create video stream." );
    return 0;
    }

  //Set up the codec.
  AVCodecContext *c = this->avStream->codec;
  c->codec_id = (CodecID)this->avOutputFormat->video_codec;
  c->codec_type = CODEC_TYPE_VIDEO;
  c->width = this->Dim[0];
  c->height = this->Dim[1];
  c->pix_fmt = PIX_FMT_YUV420P;
  //change DIV3 to MP43 fourCC to be easily playable on windows
  c->codec_tag = ('3'<<24) + ('4'<<16) + ('P'<<8) + 'M';
  //to do playback at actual recorded rate, this will need more work see also below
  c->time_base.den = this->FrameRate;
  c->time_base.num = 1;
  //about one full frame per second
  c->gop_size = this->FrameRate;

  //allow a variable quality/size tradeoff
  switch (this->Writer->GetQuality())
    {
    case 0:
      c->bit_rate = 3*1024*1024;
      break;
    case 1:
      c->bit_rate = 6*1024*1024;
      break;
    default:
      c->bit_rate = 12*1024*1024;
      break;
    }

  //apply the chosen parameters
  if (av_set_parameters(this->avFormatContext, NULL) < 0)
    {
    cerr << "Invalid output format parameters." << endl;
    return 0;
    }

  //manufacture a codec with the chosen parameters
  AVCodec *codec = avcodec_find_encoder(c->codec_id);
  if (!codec)
    {
    cerr << "Codec not found." << endl;
    return 0;
    }
  if (avcodec_open(c, codec) < 0)
    {
    cerr << "Could not open codec." << endl;
    return 0;
    }

  //create buffers for the codec to work with.

  //working compression space
  this->codecBufSize = 2*c->width*c->height*4; //hopefully this is enough
  this->codecBuf = new unsigned char[this->codecBufSize];
  if (!this->codecBuf)
    {
    cerr << "Could not make codec working space." << endl;
    return 0;
    }

  //for the output of the writer's input...
  this->rgbInput = avcodec_alloc_frame();
  if (!this->rgbInput)
    {
    cerr << "Could not make rgbInput avframe." << endl;
    return 0;
    }
  int RGBsize = avpicture_get_size(PIX_FMT_RGB24, c->width, c->height);
  unsigned char *rgb = new unsigned char[RGBsize];
  if (!rgb)
    {
    cerr << "Could not make rgbInput's buffer." << endl;
    return 0;
    }
  //The rgb buffer should get deleted when this->rgbInput is.
  avpicture_fill((AVPicture *)this->rgbInput, rgb, PIX_FMT_RGB24, c->width, c->height);

  //and for the output to the codec's input.
  this->yuvOutput = avcodec_alloc_frame();
  if (!this->yuvOutput)
    {
    cerr << "Could not make yuvOutput avframe." << endl;
    return 0;
    }
  int YUVsize = avpicture_get_size(c->pix_fmt, c->width, c->height);
  unsigned char *yuv = new unsigned char[YUVsize];
  if (!yuv)
    {
    cerr << "Could not make yuvOutput's buffer." << endl;
    return 0;
    }
  //The yuv buffer should get deleted when this->yuv_input is.
  avpicture_fill((AVPicture *)this->yuvOutput, yuv, c->pix_fmt, c->width, c->height);

  //Finally, open the file and start it off.
  if (url_fopen(&this->avFormatContext->pb, this->avFormatContext->filename, URL_WRONLY) < 0)
    {
    cerr << "Could not open " << this->Writer->GetFileName() << "." << endl;
    return 0;
    }
  this->openedFile = 1;

  av_write_header(this->avFormatContext);
  return 1;
}

//---------------------------------------------------------------------------
int vtkFFMPEGWriterInternal::Write(vtkImageData *id)
{
  id->Update();

  AVCodecContext *cc = this->avStream->codec;

  //copy the image from the input to the RGB buffer while flipping Y
  unsigned char *rgb = (unsigned char*)id->GetScalarPointer();
  unsigned char *src;
  for (int y = 0; y < cc->height; y++)
    {
    src = rgb + (cc->height-y-1) * cc->width * 3; //flip Y
    unsigned char *dest =
      &this->rgbInput->data[0][y*this->rgbInput->linesize[0]];
    memcpy((void*)dest, (void*)src, cc->width*3);
    }

  //convert that to YUV for input to the codec
  img_convert((AVPicture *)this->yuvOutput, cc->pix_fmt,
              (AVPicture *)this->rgbInput, PIX_FMT_RGB24,
              cc->width, cc->height);

  //run the encoder
  int toAdd = avcodec_encode_video(cc,
                                   this->codecBuf,
                                   this->codecBufSize,
                                   this->yuvOutput);

  //dump the compressed result to file
  if (toAdd)
    {
    //create an avpacket to output the compressed result
    AVPacket pkt;
    av_init_packet(&pkt);

   //to do playback at actual recorded rate, this will need more work
    pkt.pts = cc->coded_frame->pts;
    //pkt.dts = ?; not dure what decompression time stamp should be
    pkt.data = this->codecBuf;
    pkt.size = toAdd;
    pkt.stream_index = this->avStream->index;
    if (cc->coded_frame->key_frame) //treat keyframes well
      {
      pkt.flags |= PKT_FLAG_KEY;
      }
    pkt.duration = 0; //presentation duration in time_base units or 0 if NA
    pkt.pos = -1; //byte position in stream or -1 if NA

    toAdd = av_write_frame(this->avFormatContext, &pkt);
    }

  if (toAdd) //should not have anything left over
    {
    cerr << "Problem encoding frame." << endl;
    return 0;
    }

  return 1;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriterInternal::End()
{
  if (this->yuvOutput)
    {
    av_free(this->yuvOutput->data[0]);
    av_free(this->yuvOutput);
    this->yuvOutput = 0;
    }

  if (this->rgbInput)
    {
    av_free(this->rgbInput->data[0]);
    av_free(this->rgbInput);
    this->rgbInput = 0;
    }

  if (this->codecBuf)
    {
    av_free(this->codecBuf);
    this->codecBuf = 0;
    }

  if (this->avStream)
    {
    av_free(this->avStream);
    this->avStream = 0;
    }

  if (this->avFormatContext)
    {
    if (this->openedFile)
      {
      av_write_trailer(this->avFormatContext);
      url_fclose(&this->avFormatContext->pb);
      this->openedFile = 0;
      }

    av_free(this->avFormatContext);
    this->avFormatContext = 0;
    }

  if (this->avOutputFormat)
    {
    //Next line was done inside av_free(this->avFormatContext).
    //av_free(this->avOutputFormat);

    this->avOutputFormat = 0;
    }

  this->closedFile = 1;
}

//---------------------------------------------------------------------------
vtkStandardNewMacro(vtkFFMPEGWriter);
vtkCxxRevisionMacro(vtkFFMPEGWriter, "1.4");

//---------------------------------------------------------------------------
vtkFFMPEGWriter::vtkFFMPEGWriter()
{
  this->Internals = 0;
  this->Quality = 2;
  this->Rate = 25;
}

//---------------------------------------------------------------------------
vtkFFMPEGWriter::~vtkFFMPEGWriter()
{
  delete this->Internals;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::Start()
{
  this->Error = 1;

  if ( this->Internals )
    {
    vtkErrorMacro("Movie already started.");
    this->SetErrorCode(vtkGenericMovieWriter::InitError);
    return;
    }
  if ( this->GetInput() == NULL )
    {
    vtkErrorMacro("Please specify an input.");
    this->SetErrorCode(vtkGenericMovieWriter::NoInputError);
    return;
    }
  if (!this->FileName)
    {
    vtkErrorMacro("Please specify a filename.");
    this->SetErrorCode(vtkErrorCode::NoFileNameError);
    return;
    }

  this->Internals = new vtkFFMPEGWriterInternal(this);

  this->Error = 0;

  this->Initialized = 0;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::Write()
{
  if (this->Error)
    {
    return;
    }

  if ( !this->Internals )
    {
    vtkErrorMacro("Movie not started.");
    this->Error = 1;
    this->SetErrorCode(vtkGenericMovieWriter::InitError);
    return;
    }

  // get the data
  this->GetInput()->UpdateInformation();
  int *wExtent = this->GetInput()->GetWholeExtent();
  this->GetInput()->SetUpdateExtent(wExtent);
  this->GetInput()->Update();

  int dim[4];
  this->GetInput()->GetDimensions(dim);
  if ( this->Internals->Dim[0] == 0 && this->Internals->Dim[1] == 0 )
    {
    this->Internals->Dim[0] = dim[0];
    this->Internals->Dim[1] = dim[1];
    }

  if (this->Internals->Dim[0]!= dim[0] || this->Internals->Dim[1]!= dim[1])
    {
    vtkErrorMacro("Image not of the same size.");
    this->Error = 1;
    this->SetErrorCode(vtkGenericMovieWriter::ChangedResolutionError);
    return;
    }

  if ( !this->Initialized )
    {
    this->Internals->FrameRate = this->Rate;
    if (!this->Internals->Start())
      {
      vtkErrorMacro("Error initializing video stream.");
      this->Error = 1;
      this->SetErrorCode(vtkGenericMovieWriter::InitError);
      return;
      }
    this->Initialized = 1;
    }

  if (!this->Internals->Write(this->GetInput()))
    {
    vtkErrorMacro("Error storing image.");
    this->Error = 1;
    this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
    }
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::End()
{
  this->Internals->End();

  delete this->Internals;
  this->Internals = 0;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Quality: " << this->Quality << endl;
  os << indent << "Rate: " << this->Rate << endl;
}
<commit_msg>COMP: The last commit did not compile because it was using vtkErrorMacro outside a VTK class.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkFFMPEGWriter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkFFMPEGWriter.h"

#include "vtkImageData.h"
#include "vtkObjectFactory.h"
#include "vtkErrorCode.h"

extern "C" {
#include <ffmpeg/avformat.h>
}

//---------------------------------------------------------------------------
class vtkFFMPEGWriterInternal
{
public:
  vtkFFMPEGWriterInternal(vtkFFMPEGWriter *creator);
  ~vtkFFMPEGWriterInternal();

  int Start();
  int Write(vtkImageData *id);
  void End();

  int Dim[2];
  int FrameRate;

private:

  vtkFFMPEGWriter *Writer;

  AVFormatContext *avFormatContext;

  AVOutputFormat *avOutputFormat;

  AVStream *avStream;

  unsigned char *codecBuf;
  int codecBufSize;

  AVFrame *rgbInput;
  AVFrame *yuvOutput;

  int openedFile;
  int closedFile;
};

//---------------------------------------------------------------------------
vtkFFMPEGWriterInternal::vtkFFMPEGWriterInternal(vtkFFMPEGWriter *creator)
{
  this->Writer = creator;
  this->Dim[0] = 0;
  this->Dim[1] = 0;

  this->avFormatContext = NULL;

  this->avOutputFormat = NULL;

  this->avStream = NULL;

  this->codecBuf = NULL;
  this->rgbInput = NULL;
  this->yuvOutput = NULL;

  this->openedFile = 0;
  this->closedFile = 1;

  this->FrameRate = 25;
}

//---------------------------------------------------------------------------
vtkFFMPEGWriterInternal::~vtkFFMPEGWriterInternal()
{
  if (!this->closedFile)
    {
    this->End();
    }
}

//---------------------------------------------------------------------------
int vtkFFMPEGWriterInternal::Start()
{
  this->closedFile = 0;

  //initialize libavcodec, and register all codecs and formats
  av_register_all();

  //create the format context that wraps all of the media output structures
  this->avFormatContext = av_alloc_format_context();
  if (!this->avFormatContext)
    {
    vtkGenericWarningMacro (<< "Coult not open the format context.");
    return 0;
    }

  //choose avi media file format
  this->avOutputFormat = guess_format("avi", NULL, NULL);
  if (!this->avOutputFormat)
    {
    vtkGenericWarningMacro (<< "Could not open the avi media file format.");
    return 0;
    }

  //chosen a codec that is easily playable on windows
  this->avOutputFormat->video_codec = CODEC_ID_MSMPEG4V3;

  //assign the format to the context
  this->avFormatContext->oformat = this->avOutputFormat;

  //choose a filename for the output
  strcpy(this->avFormatContext->filename, this->Writer->GetFileName());

  //create a stream for that file
  this->avStream = av_new_stream(this->avFormatContext, 0);
  if (!this->avStream)
    {
    vtkGenericWarningMacro (<< "Could not create video stream.");
    return 0;
    }

  //Set up the codec.
  AVCodecContext *c = this->avStream->codec;
  c->codec_id = (CodecID)this->avOutputFormat->video_codec;
  c->codec_type = CODEC_TYPE_VIDEO;
  c->width = this->Dim[0];
  c->height = this->Dim[1];
  c->pix_fmt = PIX_FMT_YUV420P;
  //change DIV3 to MP43 fourCC to be easily playable on windows
  c->codec_tag = ('3'<<24) + ('4'<<16) + ('P'<<8) + 'M';
  //to do playback at actual recorded rate, this will need more work see also below
  c->time_base.den = this->FrameRate;
  c->time_base.num = 1;
  //about one full frame per second
  c->gop_size = this->FrameRate;

  //allow a variable quality/size tradeoff
  switch (this->Writer->GetQuality())
    {
    case 0:
      c->bit_rate = 3*1024*1024;
      break;
    case 1:
      c->bit_rate = 6*1024*1024;
      break;
    default:
      c->bit_rate = 12*1024*1024;
      break;
    }

  //apply the chosen parameters
  if (av_set_parameters(this->avFormatContext, NULL) < 0)
    {
    vtkGenericWarningMacro (<< "Invalid output format parameters." );
    return 0;
    }

  //manufacture a codec with the chosen parameters
  AVCodec *codec = avcodec_find_encoder(c->codec_id);
  if (!codec)
    {
    vtkGenericWarningMacro (<< "Codec not found." );
    return 0;
    }
  if (avcodec_open(c, codec) < 0)
    {
    vtkGenericWarningMacro (<< "Could not open codec.");
    return 0;
    }

  //create buffers for the codec to work with.

  //working compression space
  this->codecBufSize = 2*c->width*c->height*4; //hopefully this is enough
  this->codecBuf = new unsigned char[this->codecBufSize];
  if (!this->codecBuf)
    {
    vtkGenericWarningMacro (<< "Could not make codec working space." );
    return 0;
    }

  //for the output of the writer's input...
  this->rgbInput = avcodec_alloc_frame();
  if (!this->rgbInput)
    {
    vtkGenericWarningMacro (<< "Could not make rgbInput avframe." );
    return 0;
    }
  int RGBsize = avpicture_get_size(PIX_FMT_RGB24, c->width, c->height);
  unsigned char *rgb = new unsigned char[RGBsize];
  if (!rgb)
    {
    vtkGenericWarningMacro (<< "Could not make rgbInput's buffer." );
    return 0;
    }
  //The rgb buffer should get deleted when this->rgbInput is.
  avpicture_fill((AVPicture *)this->rgbInput, rgb, PIX_FMT_RGB24, c->width, c->height);

  //and for the output to the codec's input.
  this->yuvOutput = avcodec_alloc_frame();
  if (!this->yuvOutput)
    {
    vtkGenericWarningMacro (<< "Could not make yuvOutput avframe." );
    return 0;
    }
  int YUVsize = avpicture_get_size(c->pix_fmt, c->width, c->height);
  unsigned char *yuv = new unsigned char[YUVsize];
  if (!yuv)
    {
    vtkGenericWarningMacro (<< "Could not make yuvOutput's buffer." );
    return 0;
    }
  //The yuv buffer should get deleted when this->yuv_input is.
  avpicture_fill((AVPicture *)this->yuvOutput, yuv, c->pix_fmt, c->width, c->height);

  //Finally, open the file and start it off.
  if (url_fopen(&this->avFormatContext->pb, this->avFormatContext->filename, URL_WRONLY) < 0)
    {
    vtkGenericWarningMacro (<< "Could not open " << this->Writer->GetFileName() << "." );
    return 0;
    }
  this->openedFile = 1;

  av_write_header(this->avFormatContext);
  return 1;
}

//---------------------------------------------------------------------------
int vtkFFMPEGWriterInternal::Write(vtkImageData *id)
{
  id->Update();

  AVCodecContext *cc = this->avStream->codec;

  //copy the image from the input to the RGB buffer while flipping Y
  unsigned char *rgb = (unsigned char*)id->GetScalarPointer();
  unsigned char *src;
  for (int y = 0; y < cc->height; y++)
    {
    src = rgb + (cc->height-y-1) * cc->width * 3; //flip Y
    unsigned char *dest =
      &this->rgbInput->data[0][y*this->rgbInput->linesize[0]];
    memcpy((void*)dest, (void*)src, cc->width*3);
    }

  //convert that to YUV for input to the codec
  img_convert((AVPicture *)this->yuvOutput, cc->pix_fmt,
              (AVPicture *)this->rgbInput, PIX_FMT_RGB24,
              cc->width, cc->height);

  //run the encoder
  int toAdd = avcodec_encode_video(cc,
                                   this->codecBuf,
                                   this->codecBufSize,
                                   this->yuvOutput);

  //dump the compressed result to file
  if (toAdd)
    {
    //create an avpacket to output the compressed result
    AVPacket pkt;
    av_init_packet(&pkt);

   //to do playback at actual recorded rate, this will need more work
    pkt.pts = cc->coded_frame->pts;
    //pkt.dts = ?; not dure what decompression time stamp should be
    pkt.data = this->codecBuf;
    pkt.size = toAdd;
    pkt.stream_index = this->avStream->index;
    if (cc->coded_frame->key_frame) //treat keyframes well
      {
      pkt.flags |= PKT_FLAG_KEY;
      }
    pkt.duration = 0; //presentation duration in time_base units or 0 if NA
    pkt.pos = -1; //byte position in stream or -1 if NA

    toAdd = av_write_frame(this->avFormatContext, &pkt);
    }

  if (toAdd) //should not have anything left over
    {
    vtkGenericWarningMacro (<< "Problem encoding frame." );
    return 0;
    }

  return 1;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriterInternal::End()
{
  if (this->yuvOutput)
    {
    av_free(this->yuvOutput->data[0]);
    av_free(this->yuvOutput);
    this->yuvOutput = 0;
    }

  if (this->rgbInput)
    {
    av_free(this->rgbInput->data[0]);
    av_free(this->rgbInput);
    this->rgbInput = 0;
    }

  if (this->codecBuf)
    {
    av_free(this->codecBuf);
    this->codecBuf = 0;
    }

  if (this->avStream)
    {
    av_free(this->avStream);
    this->avStream = 0;
    }

  if (this->avFormatContext)
    {
    if (this->openedFile)
      {
      av_write_trailer(this->avFormatContext);
      url_fclose(&this->avFormatContext->pb);
      this->openedFile = 0;
      }

    av_free(this->avFormatContext);
    this->avFormatContext = 0;
    }

  if (this->avOutputFormat)
    {
    //Next line was done inside av_free(this->avFormatContext).
    //av_free(this->avOutputFormat);

    this->avOutputFormat = 0;
    }

  this->closedFile = 1;
}

//---------------------------------------------------------------------------
vtkStandardNewMacro(vtkFFMPEGWriter);
vtkCxxRevisionMacro(vtkFFMPEGWriter, "1.5");

//---------------------------------------------------------------------------
vtkFFMPEGWriter::vtkFFMPEGWriter()
{
  this->Internals = 0;
  this->Quality = 2;
  this->Rate = 25;
}

//---------------------------------------------------------------------------
vtkFFMPEGWriter::~vtkFFMPEGWriter()
{
  delete this->Internals;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::Start()
{
  this->Error = 1;

  if ( this->Internals )
    {
    vtkErrorMacro("Movie already started.");
    this->SetErrorCode(vtkGenericMovieWriter::InitError);
    return;
    }
  if ( this->GetInput() == NULL )
    {
    vtkErrorMacro("Please specify an input.");
    this->SetErrorCode(vtkGenericMovieWriter::NoInputError);
    return;
    }
  if (!this->FileName)
    {
    vtkErrorMacro("Please specify a filename.");
    this->SetErrorCode(vtkErrorCode::NoFileNameError);
    return;
    }

  this->Internals = new vtkFFMPEGWriterInternal(this);

  this->Error = 0;

  this->Initialized = 0;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::Write()
{
  if (this->Error)
    {
    return;
    }

  if ( !this->Internals )
    {
    vtkErrorMacro("Movie not started.");
    this->Error = 1;
    this->SetErrorCode(vtkGenericMovieWriter::InitError);
    return;
    }

  // get the data
  this->GetInput()->UpdateInformation();
  int *wExtent = this->GetInput()->GetWholeExtent();
  this->GetInput()->SetUpdateExtent(wExtent);
  this->GetInput()->Update();

  int dim[4];
  this->GetInput()->GetDimensions(dim);
  if ( this->Internals->Dim[0] == 0 && this->Internals->Dim[1] == 0 )
    {
    this->Internals->Dim[0] = dim[0];
    this->Internals->Dim[1] = dim[1];
    }

  if (this->Internals->Dim[0]!= dim[0] || this->Internals->Dim[1]!= dim[1])
    {
    vtkErrorMacro("Image not of the same size.");
    this->Error = 1;
    this->SetErrorCode(vtkGenericMovieWriter::ChangedResolutionError);
    return;
    }

  if ( !this->Initialized )
    {
    this->Internals->FrameRate = this->Rate;
    if (!this->Internals->Start())
      {
      vtkErrorMacro("Error initializing video stream.");
      this->Error = 1;
      this->SetErrorCode(vtkGenericMovieWriter::InitError);
      return;
      }
    this->Initialized = 1;
    }

  if (!this->Internals->Write(this->GetInput()))
    {
    vtkErrorMacro("Error storing image.");
    this->Error = 1;
    this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
    }
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::End()
{
  this->Internals->End();

  delete this->Internals;
  this->Internals = 0;
}

//---------------------------------------------------------------------------
void vtkFFMPEGWriter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "Quality: " << this->Quality << endl;
  os << indent << "Rate: " << this->Rate << endl;
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2018 The Crown developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "rpcupdate.h"

#include "init.h"
#include "clientversion.h"
#include "rpcserver.h"
#include "util.h"

#include <boost/filesystem.hpp>
#include <boost/thread.hpp>

using namespace json_spirit;
using namespace std;

bool RPCUpdate::started = false;
Object RPCUpdate::statusObj;

void RPCUpdate::Download()
{
    statusObj.clear();
    // Create temporary directory
    boost::filesystem::path dir = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
    bool result = TryCreateDirectory(dir);
    if (!result) {
        throw runtime_error("Failed to create directory" + dir.string());
    }

    // Download archive
    std::string url = updater.GetDownloadUrl();
    std::string archivePath = (dir / boost::filesystem::path(url).filename()).string();
    updater.DownloadFile(url, archivePath, &ProgressFunction);
    if (CheckSha(archivePath))
    {
        statusObj[0] = Pair("Download", "Done - " + archivePath);
    }
    else
    {
        statusObj[0] = Pair("Download", "Error. SHA-256 verification failed.");
        boost::filesystem::remove_all(dir);
    }
}

void RPCUpdate::Install()
{
    statusObj.clear();
    // Create temporary directory
    boost::filesystem::path dir = GetTempPath() / boost::filesystem::unique_path();
    bool result = TryCreateDirectory(dir);
    if (!result) {
        throw runtime_error("Failed to create directory" + dir.string());
    }

    // Download archive
    std::string url = updater.GetDownloadUrl();
    std::string archivePath = (dir / boost::filesystem::path(url).filename()).string();
    updater.DownloadFile(url, archivePath, &ProgressFunction);
    if (CheckSha(archivePath))
    {
        statusObj[0] = Pair("Download", "Done");
    }
    else
    {
        statusObj[0] = Pair("Download", "Error. SHA-256 verification failed.");
        boost::filesystem::remove_all(dir);
        return;
    }

    // Extract archive
    result = TryCreateDirectory(dir / "archive");
    if (!result) {
        throw runtime_error("Failed to create directory" + (dir / "archive").string());
    }
    std::string strCommand = "unzip -q " + archivePath + " -d " + (dir / "archive").string();
    int nErr = ::system(strCommand.c_str());
    if (nErr) {
        LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
        statusObj.push_back(Pair("Extract", "Error. Check debug.log"));
    } else {
        statusObj.push_back(Pair("Extract", "Done"));
    }

    // Copy files to /usr/
    if (!nErr) {
        strCommand = "cp -r " + (dir / "archive/*/*").string() + " /usr/";
        nErr = ::system(strCommand.c_str());
        if (nErr) {
            LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
            statusObj.push_back(Pair("Install", "Error. Check debug.log."));
        } else {
            statusObj.push_back(Pair("Install", "Done"));
        }

        // Restart crownd
        StartRestart();
    }

    boost::filesystem::remove_all(dir);
}

void RPCUpdate::ProgressFunction(curl_off_t now, curl_off_t total)
{
    int percent = 0;
    if (total != 0) {
        percent = now * 100 / total;
    }
    if (statusObj.size() == 0) {
        statusObj.push_back(Pair("Download", "In Progress"));
    }
    if ((now == total) && now != 0) {
        started = false;
        statusObj[0] = Pair("Download", "Done");
    } else if (now != total) {
        started = true;
        statusObj[0] = Pair("Download", strprintf("%0.1f/%0.1fMB, %d%%",
                                        static_cast<double>(now) / 1024 / 1024,
                                        static_cast<double>(total) / 1024 / 1024,
                                        percent));
    }
}

bool RPCUpdate::IsStarted() const
{
    return started;
}

Object RPCUpdate::GetStatusObject() const
{
    return statusObj;
}

bool RPCUpdate::CheckSha(const std::string& fileName) const
{
    bool result = false;
    std::string newSha = updater.GetDownloadSha256Sum();
    try
    {
        std::string sha = Sha256Sum(fileName);
        if (!sha.empty()) {
            if (newSha.compare(sha) == 0) {
                result = true;
            } else {
                result = false;
            }
        } else {
            result = false;
        }
    } catch(std::runtime_error &e) {
        result = false;
    }
    return result;
}

Value update(const Array& params, bool fHelp)
{
    RPCUpdate rpcUpdate;
    string strCommand;
    if (params.size() >= 1)
        strCommand = params[0].get_str();

    if (fHelp  || (strCommand != "check" && strCommand != "download" && strCommand != "status" && strCommand != "install"))
        throw runtime_error(
                "update \"command\"... ( \"passphrase\" )\n"
                "Set of commands to check and download application updates\n"
                "\nArguments:\n"
                "1. \"command\"        (string or set of strings, required) The command to execute\n"
                "2. \"passphrase\"     (string, optional) The wallet passphrase\n"
                "\nAvailable commands:\n"
                "  check        - Check for application updates\n"
                "  download     - Download a new version\n"
                "  status       - Check download status\n"
                "  install      - Install update\n"
                );
    if (!fServer)
    {
        throw runtime_error("Command is available only in server mode."
            "\ncrown-qt will automatically check and notify if there is an updates\n");
    }

    if (strCommand == "check")
    {
        if (params.size() > 1) {
            throw runtime_error("Too many parameters\n");
        }

        if (updater.Check())
        {
            // There is an update
            Object obj;
            obj.push_back(Pair("Current Version", FormatVersion(CLIENT_VERSION)));
            obj.push_back(Pair("Update Version", FormatVersion(updater.GetVersion())));
            obj.push_back(Pair("OS", updater.GetOsString()));
            obj.push_back(Pair("Url", updater.GetDownloadUrl()));
            obj.push_back(Pair("Sha256hash", updater.GetDownloadSha256Sum()));
            return obj;
        }
        return "You are running the latest version of Crown - " + FormatVersion(CLIENT_VERSION);
    }

    if (strCommand == "download")
    {
        if (!updater.Check())
        {
            return "You are running the latest version of Crown - " + FormatVersion(CLIENT_VERSION);
        }
        if (rpcUpdate.IsStarted())
        {
            return "Download is in progress. Run 'crown-cli update status' to check the status.";
        }
        boost::thread t(boost::bind(&RPCUpdate::Download, rpcUpdate));
        return "Crown download started. \nRun 'crown-cli update status' to check download status.";
    }

    if (strCommand == "status")
    {
        return rpcUpdate.GetStatusObject();
    }

    if (strCommand == "install")
    {
        if (!updater.Check())
        {
            return "You are running the latest version of Crown - " + FormatVersion(CLIENT_VERSION);
        }
        if (rpcUpdate.IsStarted())
        {
            return "Download is in progress. Run 'crown-cli update status' to check the status.";
        }
        boost::thread t(boost::bind(&RPCUpdate::Install, rpcUpdate));
        return "Crown install started. \nRun 'crown-cli update status' to check download status.";
    }
    return "";
}
<commit_msg>Added checks for updater<commit_after>// Copyright (c) 2014-2018 The Crown developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "rpcupdate.h"

#include "init.h"
#include "clientversion.h"
#include "rpcserver.h"
#include "util.h"

#include <boost/filesystem.hpp>
#include <boost/thread.hpp>

using namespace json_spirit;
using namespace std;

bool RPCUpdate::started = false;
Object RPCUpdate::statusObj;

void RPCUpdate::Download()
{
    statusObj.clear();
    // Create temporary directory
    boost::filesystem::path dir = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
    bool result = TryCreateDirectory(dir);
    if (!result) {
        throw runtime_error("Failed to create directory" + dir.string());
    }

    // Download archive
    std::string url = updater.GetDownloadUrl();
    std::string archivePath = (dir / boost::filesystem::path(url).filename()).string();
    updater.DownloadFile(url, archivePath, &ProgressFunction);
    if (CheckSha(archivePath))
    {
        statusObj[0] = Pair("Download", "Done - " + archivePath);
    }
    else
    {
        statusObj[0] = Pair("Download", "Error. SHA-256 verification failed.");
        boost::filesystem::remove_all(dir);
    }
}

void RPCUpdate::Install()
{
    statusObj.clear();
    // Create temporary directory
    boost::filesystem::path dir = GetTempPath() / boost::filesystem::unique_path();
    bool result = TryCreateDirectory(dir);
    if (!result) {
        throw runtime_error("Failed to create directory" + dir.string());
    }

    // Download archive
    std::string url = updater.GetDownloadUrl();
    std::string archivePath = (dir / boost::filesystem::path(url).filename()).string();
    updater.DownloadFile(url, archivePath, &ProgressFunction);
    if (CheckSha(archivePath))
    {
        statusObj[0] = Pair("Download", "Done");
    }
    else
    {
        statusObj[0] = Pair("Download", "Error. SHA-256 verification failed.");
        boost::filesystem::remove_all(dir);
        return;
    }

    // Extract archive
    result = TryCreateDirectory(dir / "archive");
    if (!result) {
        throw runtime_error("Failed to create directory" + (dir / "archive").string());
    }
    std::string strCommand = "unzip -q " + archivePath + " -d " + (dir / "archive").string();
    int nErr = ::system(strCommand.c_str());
    if (nErr) {
        LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
        statusObj.push_back(Pair("Extract", "Error. Check debug.log"));
    } else {
        statusObj.push_back(Pair("Extract", "Done"));
    }

    // Copy files to /usr/
    if (!nErr) {
        strCommand = "cp -r " + (dir / "archive/*/*").string() + " /usr/";
        nErr = ::system(strCommand.c_str());
        if (nErr) {
            LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
            statusObj.push_back(Pair("Install", "Error. Check debug.log."));
        } else {
            statusObj.push_back(Pair("Install", "Done"));
        }

        // Restart crownd
        StartRestart();
    }

    boost::filesystem::remove_all(dir);
}

void RPCUpdate::ProgressFunction(curl_off_t now, curl_off_t total)
{
    int percent = 0;
    if (total != 0) {
        percent = now * 100 / total;
    }
    if (statusObj.size() == 0) {
        statusObj.push_back(Pair("Download", "In Progress"));
    }
    if ((now == total) && now != 0) {
        started = false;
        statusObj[0] = Pair("Download", "Done");
    } else if (now != total) {
        started = true;
        statusObj[0] = Pair("Download", strprintf("%0.1f/%0.1fMB, %d%%",
                                        static_cast<double>(now) / 1024 / 1024,
                                        static_cast<double>(total) / 1024 / 1024,
                                        percent));
    }
}

bool RPCUpdate::IsStarted() const
{
    return started;
}

Object RPCUpdate::GetStatusObject() const
{
    return statusObj;
}

bool RPCUpdate::CheckSha(const std::string& fileName) const
{
    bool result = false;
    std::string newSha = updater.GetDownloadSha256Sum();
    try
    {
        std::string sha = Sha256Sum(fileName);
        if (!sha.empty()) {
            if (newSha.compare(sha) == 0) {
                result = true;
            } else {
                result = false;
            }
        } else {
            result = false;
        }
    } catch(std::runtime_error &e) {
        result = false;
    }
    return result;
}

Value update(const Array& params, bool fHelp)
{
    RPCUpdate rpcUpdate;
    string strCommand;
    if (params.size() >= 1)
        strCommand = params[0].get_str();

    if (fHelp  || (strCommand != "check" && strCommand != "download" && strCommand != "status" && strCommand != "install"))
        throw runtime_error(
                "update \"command\"... ( \"passphrase\" )\n"
                "Set of commands to check and download application updates\n"
                "\nArguments:\n"
                "1. \"command\"        (string or set of strings, required) The command to execute\n"
                "2. \"passphrase\"     (string, optional) The wallet passphrase\n"
                "\nAvailable commands:\n"
                "  check        - Check for application updates\n"
                "  download     - Download a new version\n"
                "  status       - Check download status\n"
                "  install      - Install update\n"
                );

    if (strCommand == "check")
    {
        if (params.size() > 1) {
            throw runtime_error("Too many parameters\n");
        }

        if (updater.Check())
        {
            // There is an update
            Object obj;
            obj.push_back(Pair("Current Version", FormatVersion(CLIENT_VERSION)));
            obj.push_back(Pair("Update Version", FormatVersion(updater.GetVersion())));
            obj.push_back(Pair("OS", updater.GetOsString()));
            obj.push_back(Pair("Url", updater.GetDownloadUrl()));
            obj.push_back(Pair("Sha256hash", updater.GetDownloadSha256Sum()));
            return obj;
        }
        return "You are running the latest version of Crown - " + FormatVersion(CLIENT_VERSION);
    }

    if (strCommand == "download")
    {
        if (!updater.Check())
        {
            return "You are running the latest version of Crown - " + FormatVersion(CLIENT_VERSION);
        }
        if (rpcUpdate.IsStarted())
        {
            return "Download is in progress. Run 'crown-cli update status' to check the status.";
        }
        boost::thread t(boost::bind(&RPCUpdate::Download, rpcUpdate));
        return "Crown download started. \nRun 'crown-cli update status' to check download status.";
    }

    if (strCommand == "status")
    {
        return rpcUpdate.GetStatusObject();
    }

    if (strCommand == "install")
    {
        if (!fServer)
        {
            throw runtime_error("Command is available only in server mode."
                "\ncrown-qt will automatically check and notify if there is an updates\n");
        }

        if (updater.GetOS() != Updater::LINUX_32 && updater.GetOS() != Updater::LINUX_64)
        {
            throw runtime_error("Command is available only in Linux.");
        }

        if (::system("command -v unzip"))
        {
            throw runtime_error("The command 'unzip' could not be found. Please install it and try again.");
        }

        if (!updater.Check())
        {
            return "You are running the latest version of Crown - " + FormatVersion(CLIENT_VERSION);
        }
        if (rpcUpdate.IsStarted())
        {
            return "Download is in progress. Run 'crown-cli update status' to check the status.";
        }
        boost::thread t(boost::bind(&RPCUpdate::Install, rpcUpdate));
        return "Crown install started. \nRun 'crown-cli update status' to check download status.";
    }
    return "";
}
<|endoftext|>


<commit_before>#include "code_it_pr2/robot_api.h"

#include <string>
#include <vector>

#include "boost/shared_ptr.hpp"
#include "code_it_msgs/ArmId.h"
#include "code_it_msgs/AskMultipleChoice.h"
#include "code_it_msgs/DisplayMessage.h"
#include "code_it_msgs/FindCustomLandmarks.h"
#include "code_it_msgs/FindObjects.h"
#include "code_it_msgs/GripperId.h"
#include "code_it_msgs/Landmark.h"
#include "code_it_msgs/LookAt.h"
#include "code_it_msgs/Pick.h"
#include "code_it_msgs/Place.h"
#include "code_it_msgs/Say.h"
#include "code_it_msgs/SetGripper.h"
#include "code_it_msgs/TuckArms.h"
#include "geometry_msgs/PoseStamped.h"
#include "geometry_msgs/Vector3.h"
#include "object_search_msgs/Match.h"
#include "object_search_msgs/GetObjectInfo.h"
#include "object_search_msgs/SearchFromDb.h"
#include "pr2_pbd_interaction/ExecuteAction.h"
#include "pr2_pbd_interaction/Landmark.h"
#include "rapid_perception/pr2.h"
#include "rapid_perception/scene.h"
#include "rapid_perception/scene_viz.h"
#include "rapid_pr2/pr2.h"
#include "rapid_ros/publisher.h"
#include "ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "std_msgs/Bool.h"
#include "std_msgs/String.h"
#include "tf/transform_listener.h"
#include "visualization_msgs/Marker.h"

namespace rpe = rapid::perception;
using boost::shared_ptr;
using pr2_pbd_interaction::ExecuteAction;
using pr2_pbd_interaction::ExecuteGoal;
using pr2_pbd_interaction::ExecuteResult;
using std::string;
using visualization_msgs::Marker;

namespace code_it_pr2 {
RobotApi::RobotApi(rapid::pr2::Pr2* robot, const ros::Publisher& error_pub,
                   const rapid_ros::Publisher<Marker>& marker_pub,
                   rapid_ros::ActionClient<ExecuteAction>& pbd_client,
                   const ros::ServiceClient& find_landmark,
                   const ros::ServiceClient& get_landmark_info)
    : robot_(robot),
      error_pub_(error_pub),
      tf_listener_(),
      marker_pub_(marker_pub),
      scene_(),
      scene_viz_(&marker_pub_),
      scene_has_parsed_(false),
      pbd_client_(pbd_client),
      find_landmark_(find_landmark),
      get_landmark_info_(get_landmark_info) {}

bool RobotApi::AskMultipleChoice(code_it_msgs::AskMultipleChoiceRequest& req,
                                 code_it_msgs::AskMultipleChoiceResponse& res) {
  string choice;
  bool success =
      robot_->display()->AskMultipleChoice(req.question, req.choices, &choice);
  res.choice = choice;
  if (!success) {
    res.error = errors::ASK_MC_QUESTION;
  }
  return true;
}

bool RobotApi::DisplayMessage(code_it_msgs::DisplayMessageRequest& req,
                              code_it_msgs::DisplayMessageResponse& res) {
  bool success = robot_->display()->ShowMessage(req.h1_text, req.h2_text);
  if (!success) {
    res.error = errors::DISPLAY_MESSAGE;
  }
  return true;
}

bool RobotApi::FindCustomLandmarks(
    code_it_msgs::FindCustomLandmarksRequest& req,
    code_it_msgs::FindCustomLandmarksResponse& res) {
  object_search_msgs::GetObjectInfoRequest info_req;
  info_req.db_id = req.db_id;
  object_search_msgs::GetObjectInfoResponse info_res;
  get_landmark_info_.call(info_req, info_res);

  object_search_msgs::SearchFromDbRequest search_req;
  search_req.object_id = req.db_id;
  search_req.min_results = 0;
  search_req.is_tabletop = req.is_tabletop;
  search_req.max_error = 0;  // 0 value means get from parameter server.
  object_search_msgs::SearchFromDbResponse search_res;
  bool success = find_landmark_.call(search_req, search_res);
  if (!success) {
    res.error = errors::FIND_LANDMARK_FAILED;
    return true;
  }
  // Convert object_search Matches to code_it Landmarks.
  for (size_t i = 0; i < search_res.matches.size(); ++i) {
    const object_search_msgs::Match& match = search_res.matches[i];
    code_it_msgs::Landmark landmark;
    landmark.name = info_res.name;
    landmark.pose.pose = match.pose;
    landmark.scale = info_res.dimensions;
    landmark.db_id = req.db_id;
    res.landmarks.push_back(landmark);
  }

  return true;
}

bool RobotApi::FindObjects(code_it_msgs::FindObjectsRequest& req,
                           code_it_msgs::FindObjectsResponse& res) {
  bool success = rpe::pr2::GetManipulationScene(tf_listener_, &scene_);
  if (!success) {
    res.error = errors::GET_SCENE;
    return true;
  }
  scene_viz_.set_scene(scene_);
  scene_viz_.Visualize();
  scene_has_parsed_ = true;
  rpe::HSurface tt = scene_.primary_surface();
  const std::vector<rpe::Object>& objects = tt.objects();
  for (size_t i = 0; i < objects.size(); ++i) {
    const rpe::Object& obj = objects[i];
    code_it_msgs::Object msg;
    msg.name = obj.name();
    msg.pose = obj.pose();
    msg.scale = obj.scale();
    res.objects.push_back(msg);
  }
  return true;
}

bool RobotApi::IsGripperOpen(code_it_msgs::IsGripperOpenRequest& req,
                             code_it_msgs::IsGripperOpenResponse& res) {
  if (req.gripper.id == code_it_msgs::GripperId::RIGHT) {
    res.is_open = robot_->right_gripper()->IsOpen();
  } else if (req.gripper.id == code_it_msgs::GripperId::LEFT) {
    res.is_open = robot_->left_gripper()->IsOpen();
  } else {
    res.error = errors::IS_OPEN_AMBIG;
    return true;
  }
  return true;
}

bool RobotApi::LookAt(code_it_msgs::LookAtRequest& req,
                      code_it_msgs::LookAtResponse& res) {
  bool success = robot_->head()->LookAt(req.target);
  if (!success) {
    res.error = errors::LOOK_AT;
  }
  return true;
}

bool RobotApi::Pick(code_it_msgs::PickRequest& req,
                    code_it_msgs::PickResponse& res) {
  if (!scene_has_parsed_) {
    res.error = errors::PICK_SCENE_NOT_PARSED;
    return true;
  }
  bool has_left_object = robot_->left_gripper()->is_holding_object();
  bool has_right_object = robot_->right_gripper()->is_holding_object();

  // Check if both hands are full
  if (has_left_object && has_right_object) {
    res.error = errors::PICK_ARMS_FULL;
    return true;
  }

  // If using the default arm, use whichever arm is free, or the right arm if
  // both arms are free.
  int8_t arm_id = req.arm.arm_id;
  if (arm_id == code_it_msgs::ArmId::DEFAULT) {
    if (has_left_object && !has_right_object) {
      arm_id = code_it_msgs::ArmId::RIGHT;
    } else if (!has_left_object && has_right_object) {
      arm_id = code_it_msgs::ArmId::LEFT;
    } else {
      arm_id = code_it_msgs::ArmId::RIGHT;
    }
  }

  rapid::perception::Object object;
  if (!scene_.GetObject(req.object.name, &object)) {
    res.error = errors::PICK_OBJECT_NOT_FOUND;
    return true;
  }
  bool success = false;
  if (arm_id == code_it_msgs::ArmId::LEFT) {
    if (has_left_object) {
      res.error = errors::PICK_LEFT_FULL;
      return true;
    }
    success = robot_->left_picker()->Pick(object);
  } else {
    if (has_right_object) {
      res.error = errors::PICK_RIGHT_FULL;
      return true;
    }
    success = robot_->right_picker()->Pick(object);
  }
  if (!success) {
    res.error = errors::PICK_OBJECT;
    return true;
  }
  return true;
}

bool RobotApi::Place(code_it_msgs::PlaceRequest& req,
                     code_it_msgs::PlaceResponse& res) {
  bool has_left_object = robot_->left_gripper()->is_holding_object();
  bool has_right_object = robot_->right_gripper()->is_holding_object();

  // Check if both hands are empty
  if (!has_left_object && !has_right_object) {
    res.error = errors::PLACE_NO_OBJECTS;
    return true;
  }

  // If using default arm, default to whichever arm has an object, or the right
  // arm if both arms have objects.
  int8_t arm_id = req.arm.arm_id;
  if (arm_id == code_it_msgs::ArmId::DEFAULT) {
    if (has_left_object && !has_right_object) {
      arm_id = code_it_msgs::ArmId::LEFT;
    } else {
      arm_id = code_it_msgs::ArmId::RIGHT;
    }
  }
  if (arm_id == code_it_msgs::ArmId::LEFT && !has_left_object) {
    res.error = errors::PLACE_NO_LEFT_OBJECT;
    return true;
  }
  if (arm_id == code_it_msgs::ArmId::RIGHT && !has_right_object) {
    res.error = errors::PLACE_NO_RIGHT_OBJECT;
    return true;
  }

  // Get the tabletop.
  rpe::Scene scene;
  bool success = rpe::pr2::GetManipulationScene(tf_listener_, &scene);
  if (!success) {
    res.error = errors::GET_SCENE;
    return true;
  }
  scene_viz_.set_scene(scene_);
  scene_viz_.Visualize();
  const rpe::HSurface& tt = scene.primary_surface();

  if (arm_id == code_it_msgs::ArmId::LEFT) {
    rpe::Object obj;
    robot_->left_gripper()->HeldObject(&obj);
    success = robot_->left_placer()->Place(obj, tt);
  } else {
    rpe::Object obj;
    robot_->right_gripper()->HeldObject(&obj);
    success = robot_->right_placer()->Place(obj, tt);
  }
  if (!success) {
    res.error = errors::PLACE_OBJECT;
    return true;
  }
  return true;
}

bool RobotApi::RunPbdAction(code_it_msgs::RunPbdActionRequest& req,
                            code_it_msgs::RunPbdActionResponse& res) {
  ExecuteGoal goal;
  goal.action_id = req.action_id;

  // Convert code_it landmarks to PbD landmarks.
  for (size_t i = 0; i < req.landmarks.size(); ++i) {
    pr2_pbd_interaction::Landmark landmark;
    landmark.name = req.landmarks[i].name;
    landmark.pose = req.landmarks[i].pose.pose;
    landmark.dimensions = req.landmarks[i].scale;
    landmark.db_id = req.landmarks[i].db_id;
    goal.landmarks.push_back(landmark);
  }

  pbd_client_.sendGoal(goal);
  bool on_time = pbd_client_.waitForResult();
  if (!on_time) {
    res.error = errors::PBD_ACTION_TIMED_OUT;
    return true;
  }
  actionlib::SimpleClientGoalState state = pbd_client_.getState();
  if (state == state.SUCCEEDED) {
  } else if (state == state.ABORTED) {
    res.error = "Execution aborted: " + state.getText();
  } else {
    res.error = errors::PBD_ACTION_FAILED;
  }
  ExecuteResult::ConstPtr result = pbd_client_.getResult();

  return true;
}

bool RobotApi::Say(code_it_msgs::SayRequest& req,
                   code_it_msgs::SayResponse& res) {
  robot_->sound()->Say(req.text);
  return true;
}

bool RobotApi::SetGripper(code_it_msgs::SetGripperRequest& req,
                          code_it_msgs::SetGripperResponse& res) {
  if (req.gripper.id == code_it_msgs::GripperId::LEFT) {
    if (req.action == code_it_msgs::SetGripperRequest::OPEN) {
      robot_->left_gripper()->Open(req.max_effort);
    } else if (req.action == code_it_msgs::SetGripperRequest::CLOSE) {
      robot_->left_gripper()->Close(req.max_effort);
    }
  } else {
    if (req.action == code_it_msgs::SetGripperRequest::OPEN) {
      robot_->right_gripper()->Open(req.max_effort);
    } else if (req.action == code_it_msgs::SetGripperRequest::CLOSE) {
      robot_->right_gripper()->Close(req.max_effort);
    }
  }
  return true;
}

bool RobotApi::TuckArms(code_it_msgs::TuckArmsRequest& req,
                        code_it_msgs::TuckArmsResponse& res) {
  bool success = true;
  if (req.tuck_left && req.tuck_right) {
    success = robot_->tuck_arms()->TuckArms();
  } else if (req.tuck_left && !req.tuck_right) {
    success = robot_->tuck_arms()->DeployRight();
  } else if (!req.tuck_left && req.tuck_right) {
    success = robot_->tuck_arms()->DeployLeft();
  } else {
    success = robot_->tuck_arms()->DeployArms();
  }
  if (!success) {
    res.error = errors::TUCK_DEPLOY;
    return true;
  }
  return true;
}

void RobotApi::HandleProgramStopped(const std_msgs::Bool& msg) {
  if (msg.data) {
    return;  // Program is running, nothing to do.
  }
  bool success = robot_->display()->ShowDefault();
  if (!success) {
    PublishError(errors::RESET_SCREEN_ON_STOP);
  }
}

void RobotApi::PublishError(const string& error) {
  std_msgs::String error_msg;
  error_msg.data = error;
  error_pub_.publish(error_msg);
  ROS_ERROR("%s", error.c_str());
}
}  // namespace code_it_pr2
<commit_msg>Implemented name lookup for findCustomLandmarks.<commit_after>#include "code_it_pr2/robot_api.h"

#include <string>
#include <vector>

#include "boost/shared_ptr.hpp"
#include "code_it_msgs/ArmId.h"
#include "code_it_msgs/AskMultipleChoice.h"
#include "code_it_msgs/DisplayMessage.h"
#include "code_it_msgs/FindCustomLandmarks.h"
#include "code_it_msgs/FindObjects.h"
#include "code_it_msgs/GripperId.h"
#include "code_it_msgs/Landmark.h"
#include "code_it_msgs/LookAt.h"
#include "code_it_msgs/Pick.h"
#include "code_it_msgs/Place.h"
#include "code_it_msgs/Say.h"
#include "code_it_msgs/SetGripper.h"
#include "code_it_msgs/TuckArms.h"
#include "geometry_msgs/PoseStamped.h"
#include "geometry_msgs/Vector3.h"
#include "object_search_msgs/Match.h"
#include "object_search_msgs/GetObjectInfo.h"
#include "object_search_msgs/SearchFromDb.h"
#include "pr2_pbd_interaction/ExecuteAction.h"
#include "pr2_pbd_interaction/Landmark.h"
#include "rapid_perception/pr2.h"
#include "rapid_perception/scene.h"
#include "rapid_perception/scene_viz.h"
#include "rapid_pr2/pr2.h"
#include "rapid_ros/publisher.h"
#include "ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "std_msgs/Bool.h"
#include "std_msgs/String.h"
#include "tf/transform_listener.h"
#include "visualization_msgs/Marker.h"

namespace rpe = rapid::perception;
using boost::shared_ptr;
using pr2_pbd_interaction::ExecuteAction;
using pr2_pbd_interaction::ExecuteGoal;
using pr2_pbd_interaction::ExecuteResult;
using std::string;
using visualization_msgs::Marker;

namespace code_it_pr2 {
RobotApi::RobotApi(rapid::pr2::Pr2* robot, const ros::Publisher& error_pub,
                   const rapid_ros::Publisher<Marker>& marker_pub,
                   rapid_ros::ActionClient<ExecuteAction>& pbd_client,
                   const ros::ServiceClient& find_landmark,
                   const ros::ServiceClient& get_landmark_info)
    : robot_(robot),
      error_pub_(error_pub),
      tf_listener_(),
      marker_pub_(marker_pub),
      scene_(),
      scene_viz_(&marker_pub_),
      scene_has_parsed_(false),
      pbd_client_(pbd_client),
      find_landmark_(find_landmark),
      get_landmark_info_(get_landmark_info) {}

bool RobotApi::AskMultipleChoice(code_it_msgs::AskMultipleChoiceRequest& req,
                                 code_it_msgs::AskMultipleChoiceResponse& res) {
  string choice;
  bool success =
      robot_->display()->AskMultipleChoice(req.question, req.choices, &choice);
  res.choice = choice;
  if (!success) {
    res.error = errors::ASK_MC_QUESTION;
  }
  return true;
}

bool RobotApi::DisplayMessage(code_it_msgs::DisplayMessageRequest& req,
                              code_it_msgs::DisplayMessageResponse& res) {
  bool success = robot_->display()->ShowMessage(req.h1_text, req.h2_text);
  if (!success) {
    res.error = errors::DISPLAY_MESSAGE;
  }
  return true;
}

bool RobotApi::FindCustomLandmarks(
    code_it_msgs::FindCustomLandmarksRequest& req,
    code_it_msgs::FindCustomLandmarksResponse& res) {
  object_search_msgs::GetObjectInfoRequest info_req;
  info_req.db_id = req.db_id;
  info_req.name = req.name;
  object_search_msgs::GetObjectInfoResponse info_res;
  get_landmark_info_.call(info_req, info_res);

  object_search_msgs::SearchFromDbRequest search_req;
  search_req.object_id = req.db_id;
  search_req.min_results = 0;
  search_req.is_tabletop = req.is_tabletop;
  search_req.max_error = 0;  // 0 value means get from parameter server.
  object_search_msgs::SearchFromDbResponse search_res;
  bool success = find_landmark_.call(search_req, search_res);
  if (!success) {
    res.error = errors::FIND_LANDMARK_FAILED;
    return true;
  }
  // Convert object_search Matches to code_it Landmarks.
  for (size_t i = 0; i < search_res.matches.size(); ++i) {
    const object_search_msgs::Match& match = search_res.matches[i];
    code_it_msgs::Landmark landmark;
    landmark.name = info_res.name;
    landmark.pose.pose = match.pose;
    landmark.scale = info_res.dimensions;
    landmark.db_id = req.db_id;
    res.landmarks.push_back(landmark);
  }

  return true;
}

bool RobotApi::FindObjects(code_it_msgs::FindObjectsRequest& req,
                           code_it_msgs::FindObjectsResponse& res) {
  bool success = rpe::pr2::GetManipulationScene(tf_listener_, &scene_);
  if (!success) {
    res.error = errors::GET_SCENE;
    return true;
  }
  scene_viz_.set_scene(scene_);
  scene_viz_.Visualize();
  scene_has_parsed_ = true;
  rpe::HSurface tt = scene_.primary_surface();
  const std::vector<rpe::Object>& objects = tt.objects();
  for (size_t i = 0; i < objects.size(); ++i) {
    const rpe::Object& obj = objects[i];
    code_it_msgs::Object msg;
    msg.name = obj.name();
    msg.pose = obj.pose();
    msg.scale = obj.scale();
    res.objects.push_back(msg);
  }
  return true;
}

bool RobotApi::IsGripperOpen(code_it_msgs::IsGripperOpenRequest& req,
                             code_it_msgs::IsGripperOpenResponse& res) {
  if (req.gripper.id == code_it_msgs::GripperId::RIGHT) {
    res.is_open = robot_->right_gripper()->IsOpen();
  } else if (req.gripper.id == code_it_msgs::GripperId::LEFT) {
    res.is_open = robot_->left_gripper()->IsOpen();
  } else {
    res.error = errors::IS_OPEN_AMBIG;
    return true;
  }
  return true;
}

bool RobotApi::LookAt(code_it_msgs::LookAtRequest& req,
                      code_it_msgs::LookAtResponse& res) {
  bool success = robot_->head()->LookAt(req.target);
  if (!success) {
    res.error = errors::LOOK_AT;
  }
  return true;
}

bool RobotApi::Pick(code_it_msgs::PickRequest& req,
                    code_it_msgs::PickResponse& res) {
  if (!scene_has_parsed_) {
    res.error = errors::PICK_SCENE_NOT_PARSED;
    return true;
  }
  bool has_left_object = robot_->left_gripper()->is_holding_object();
  bool has_right_object = robot_->right_gripper()->is_holding_object();

  // Check if both hands are full
  if (has_left_object && has_right_object) {
    res.error = errors::PICK_ARMS_FULL;
    return true;
  }

  // If using the default arm, use whichever arm is free, or the right arm if
  // both arms are free.
  int8_t arm_id = req.arm.arm_id;
  if (arm_id == code_it_msgs::ArmId::DEFAULT) {
    if (has_left_object && !has_right_object) {
      arm_id = code_it_msgs::ArmId::RIGHT;
    } else if (!has_left_object && has_right_object) {
      arm_id = code_it_msgs::ArmId::LEFT;
    } else {
      arm_id = code_it_msgs::ArmId::RIGHT;
    }
  }

  rapid::perception::Object object;
  if (!scene_.GetObject(req.object.name, &object)) {
    res.error = errors::PICK_OBJECT_NOT_FOUND;
    return true;
  }
  bool success = false;
  if (arm_id == code_it_msgs::ArmId::LEFT) {
    if (has_left_object) {
      res.error = errors::PICK_LEFT_FULL;
      return true;
    }
    success = robot_->left_picker()->Pick(object);
  } else {
    if (has_right_object) {
      res.error = errors::PICK_RIGHT_FULL;
      return true;
    }
    success = robot_->right_picker()->Pick(object);
  }
  if (!success) {
    res.error = errors::PICK_OBJECT;
    return true;
  }
  return true;
}

bool RobotApi::Place(code_it_msgs::PlaceRequest& req,
                     code_it_msgs::PlaceResponse& res) {
  bool has_left_object = robot_->left_gripper()->is_holding_object();
  bool has_right_object = robot_->right_gripper()->is_holding_object();

  // Check if both hands are empty
  if (!has_left_object && !has_right_object) {
    res.error = errors::PLACE_NO_OBJECTS;
    return true;
  }

  // If using default arm, default to whichever arm has an object, or the right
  // arm if both arms have objects.
  int8_t arm_id = req.arm.arm_id;
  if (arm_id == code_it_msgs::ArmId::DEFAULT) {
    if (has_left_object && !has_right_object) {
      arm_id = code_it_msgs::ArmId::LEFT;
    } else {
      arm_id = code_it_msgs::ArmId::RIGHT;
    }
  }
  if (arm_id == code_it_msgs::ArmId::LEFT && !has_left_object) {
    res.error = errors::PLACE_NO_LEFT_OBJECT;
    return true;
  }
  if (arm_id == code_it_msgs::ArmId::RIGHT && !has_right_object) {
    res.error = errors::PLACE_NO_RIGHT_OBJECT;
    return true;
  }

  // Get the tabletop.
  rpe::Scene scene;
  bool success = rpe::pr2::GetManipulationScene(tf_listener_, &scene);
  if (!success) {
    res.error = errors::GET_SCENE;
    return true;
  }
  scene_viz_.set_scene(scene_);
  scene_viz_.Visualize();
  const rpe::HSurface& tt = scene.primary_surface();

  if (arm_id == code_it_msgs::ArmId::LEFT) {
    rpe::Object obj;
    robot_->left_gripper()->HeldObject(&obj);
    success = robot_->left_placer()->Place(obj, tt);
  } else {
    rpe::Object obj;
    robot_->right_gripper()->HeldObject(&obj);
    success = robot_->right_placer()->Place(obj, tt);
  }
  if (!success) {
    res.error = errors::PLACE_OBJECT;
    return true;
  }
  return true;
}

bool RobotApi::RunPbdAction(code_it_msgs::RunPbdActionRequest& req,
                            code_it_msgs::RunPbdActionResponse& res) {
  ExecuteGoal goal;
  goal.action_id = req.action_id;

  // Convert code_it landmarks to PbD landmarks.
  for (size_t i = 0; i < req.landmarks.size(); ++i) {
    pr2_pbd_interaction::Landmark landmark;
    landmark.name = req.landmarks[i].name;
    landmark.pose = req.landmarks[i].pose.pose;
    landmark.dimensions = req.landmarks[i].scale;
    landmark.db_id = req.landmarks[i].db_id;
    goal.landmarks.push_back(landmark);
  }

  pbd_client_.sendGoal(goal);
  bool on_time = pbd_client_.waitForResult();
  if (!on_time) {
    res.error = errors::PBD_ACTION_TIMED_OUT;
    return true;
  }
  actionlib::SimpleClientGoalState state = pbd_client_.getState();
  if (state == state.SUCCEEDED) {
  } else if (state == state.ABORTED) {
    res.error = "Execution aborted: " + state.getText();
  } else {
    res.error = errors::PBD_ACTION_FAILED;
  }
  ExecuteResult::ConstPtr result = pbd_client_.getResult();

  return true;
}

bool RobotApi::Say(code_it_msgs::SayRequest& req,
                   code_it_msgs::SayResponse& res) {
  robot_->sound()->Say(req.text);
  return true;
}

bool RobotApi::SetGripper(code_it_msgs::SetGripperRequest& req,
                          code_it_msgs::SetGripperResponse& res) {
  if (req.gripper.id == code_it_msgs::GripperId::LEFT) {
    if (req.action == code_it_msgs::SetGripperRequest::OPEN) {
      robot_->left_gripper()->Open(req.max_effort);
    } else if (req.action == code_it_msgs::SetGripperRequest::CLOSE) {
      robot_->left_gripper()->Close(req.max_effort);
    }
  } else {
    if (req.action == code_it_msgs::SetGripperRequest::OPEN) {
      robot_->right_gripper()->Open(req.max_effort);
    } else if (req.action == code_it_msgs::SetGripperRequest::CLOSE) {
      robot_->right_gripper()->Close(req.max_effort);
    }
  }
  return true;
}

bool RobotApi::TuckArms(code_it_msgs::TuckArmsRequest& req,
                        code_it_msgs::TuckArmsResponse& res) {
  bool success = true;
  if (req.tuck_left && req.tuck_right) {
    success = robot_->tuck_arms()->TuckArms();
  } else if (req.tuck_left && !req.tuck_right) {
    success = robot_->tuck_arms()->DeployRight();
  } else if (!req.tuck_left && req.tuck_right) {
    success = robot_->tuck_arms()->DeployLeft();
  } else {
    success = robot_->tuck_arms()->DeployArms();
  }
  if (!success) {
    res.error = errors::TUCK_DEPLOY;
    return true;
  }
  return true;
}

void RobotApi::HandleProgramStopped(const std_msgs::Bool& msg) {
  if (msg.data) {
    return;  // Program is running, nothing to do.
  }
  bool success = robot_->display()->ShowDefault();
  if (!success) {
    PublishError(errors::RESET_SCREEN_ON_STOP);
  }
}

void RobotApi::PublishError(const string& error) {
  std_msgs::String error_msg;
  error_msg.data = error;
  error_pub_.publish(error_msg);
  ROS_ERROR("%s", error.c_str());
}
}  // namespace code_it_pr2
<|endoftext|>


<commit_before>//
//  main.cpp
//  prel
//
//  Created by George Oblapenko on 11/11/14.
//  Copyright (c) 2014 George Oblapenko. All rights reserved.
//

#include <iostream>
#include <kineticlib.h>

int main(int argc, const char * argv[]) {
double start_T = 2000.; // the start temperature
	double end_T = 10000.0; // the end temperature
	int points_amt = 50; // the amount of points
	double xN = 0.5; // the relative numeric density of atomic nitrogen
	double xN2 = 1. - xN;

	std::string cs_model = "VSS";  // the dissociation cross-section model

	double R_react_N2, R_react_N; // relaxation terms
	arma::vec T_array = arma::linspace<arma::vec>(start_T, end_T, points_amt); // start value of T, end value of T, amount of steps
	arma::vec prel = arma::zeros(50); // array of relaxation pressure values
	double p = 100000.0; // atmospheric pressure

	klib::MoleculeOneT N2 = klib::MoleculeOneT("N2");
	klib::Atom N = klib::Atom("N");
	arma::vec idata_N2N2 = klib::load_elastic_parameters(N2, N2); // N2 + N2 elastic interaction data
	arma::vec idata_N2N = klib::load_elastic_parameters(N2, N); // N2 + N elastic interaction data
	arma::vec ddata_N2N2 = klib::load_dissociation_parameters(N2, N2); // N2 + N2 dissociation data
	arma::vec ddata_N2N = klib::load_dissociation_parameters(N2, N); // N2 + N dissociation data
	arma::mat33 beta_matrix; // the matrix of beta integral brackets
	arma::vec3 right_parts; // the right-hand side of the system
	arma::vec3 results; // the values of the expansion coefficients g_{c,pq} - the order is g_{N2,10}, g_{N2,01}, g_{N,10}
	double T, n, rho, omega11_N2N, tau_rot_N2N, tau_rot_N2N2, eta_zeta_N2N2, eta_zeta_N2N, cV, SJsl, PJsl, SJslN2, PJslN2; // the numeric density of the mixture, the density of the mixture, Omega^{(1,1)}_{N2,N}, rotational relaxation times for N2+N and N2+N2, the quantity 4T \pi / (\eta_{cd} * \xi_{cd}), the quantity dE/dT
	double tmp_int00 = 0.0;
	beta_matrix.at(0, 0) = 1.5 * (1. - xN);
	beta_matrix.at(0, 2) = 1.5 * xN; // these appear due to the constraint conditions and are independent of temperature
	beta_matrix.zeros();
	right_parts[0] = 0.;
	for (int i = 0; i < points_amt; i++) {
		T = T_array[i];
		n = p / (KLIB_CONST_K * T);
		N2.renorm(T, xN2 * n);
		rho = xN2 * n * N2.mass + xN * n * N.mass;
		omega11_N2N = klib::omega(T, 1, 1, idata_N2N, "ESA", true, true); // we set nokt to true so that the result is of order 10e-07 instead of 10e-16
		tau_rot_N2N = klib::rot_rel_time_vss(T, idata_N2N, N2, n);
		tau_rot_N2N2 = klib::rot_rel_time_vss(T, idata_N2N2, N2, n);
		eta_zeta_N2N2 = 1. / (n * KLIB_CONST_K * tau_rot_N2N2);
		eta_zeta_N2N = 1. / (n * KLIB_CONST_K * tau_rot_N2N);
		cV = 1.5 * KLIB_CONST_K * n / rho + xN2 * (N2.mass * n / rho) * (N2.crot + N2.E_vibr_dT(T));
		beta_matrix.at(0, 1) = xN2 * klib::wt_poly_norm(T, N2);

		beta_matrix.at(1, 0) = -xN2 * N2.mass * N2.crot * (xN * (0.33333) * eta_zeta_N2N + xN2 * eta_zeta_N2N2); // does vibrational relaxation time play any significant role?
		beta_matrix.at(1, 1) = xN2 * N2.mass * N2.crot * (xN * eta_zeta_N2N + xN2 * eta_zeta_N2N2);
		beta_matrix.at(2, 0) = (2. / 9.) * xN2 * xN * (-16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);
		beta_matrix.at(2, 2) = (2. / 9.) * xN2 * xN * (16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);

		beta_matrix.at(1, 0) /= sqrt(KLIB_CONST_K * T);
		beta_matrix.at(1, 1) /= sqrt(KLIB_CONST_K * T);
		R_react_N2 = -klib::diss_rate_treanor_marrone(T, ddata_N2N, N2) * (xN * n) * (xN2 * n);

		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2; // this is a binary mixture and the relaxation terms are related in a simple way

		SJsl = 0.0;
		PJsl = 0.0;
		SJslN2 = 0.0;
		PJslN2 = 0.0;

		for (int vl = 0; vl <= N2.num_vibr; vl++) {
			tmp_int00 = 8 * klib::diss_integral(T, 0, idata_N2N, N2, vl, true, true, cs_model, true);
			SJsl += (1. / 3.) * (12 * tmp_int00  - klib::diss_integral(T, 1, idata_N2N, N2, vl, true, true, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJsl += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * tmp_int00 * N2.vibr_exp(T, vl) / N2.Z_vibr(T);

			SJslN2 += (1. / 2.) * (12 * klib::diss_integral(T, 0, idata_N2N2, N2, vl, true, true, cs_model, true) - 8 * klib::diss_integral(T, 1, idata_N2N2, N2, vl, true, true, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJslN2 += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * 8 * klib::diss_integral(T, 0, idata_N2N2, N2, vl, true, true, cs_model, true) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
		}

		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJsl * (xN * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV) - 2 * 1.5 * SJsl * (xN * xN2) * n;
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "\nprel_{N2+N}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);

		R_react_N2 = klib::diss_rate_treanor_marrone(T, ddata_N2N2, N2) * (xN2 * n) * (xN2 * n);
		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2;
		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJslN2 * (xN2 * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV) - 2 * 1.5 * SJslN2 * (xN2 * xN2) * n;
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "; prel_{N2+N2}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);
	}
}
<commit_msg>Some fixes for the N2+N reaction<commit_after>//
//  main.cpp
//  prel
//
//  Created by George Oblapenko on 11/11/14.
//  Copyright (c) 2014 George Oblapenko. All rights reserved.
//

#include <iostream>
#include <kineticlib.h>

int main(int argc, const char * argv[]) {
	double start_T = 2000.; // the start temperature
	double end_T = 10000.0; // the end temperature
	double p = 100000.0; // atmospheric pressure
	double xN = 0.5; // the relative numeric density of atomic nitrogen
	double xN2 = 1. - xN;

	std::string cs_model = "VSS";  // the dissociation cross-section model
	bool vl_dependent = false;  // whether the dissociation cross-section is dependent on the vibrational level of the dissociating molecule

	int points_amt = 50; // the amount of points
	arma::vec T_array = arma::linspace<arma::vec>(start_T, end_T, points_amt); // start value of T, end value of T, amount of steps
	arma::vec prel = arma::zeros(50); // array of relaxation pressure values

	klib::MoleculeOneT N2 = klib::MoleculeOneT("N2");
	klib::Atom N = klib::Atom("N");
	arma::vec idata_N2N2 = klib::load_elastic_parameters(N2, N2); // N2 + N2 elastic interaction data
	arma::vec idata_N2N = klib::load_elastic_parameters(N2, N); // N2 + N elastic interaction data
	arma::vec ddata_N2N2 = klib::load_dissociation_parameters(N2, N2); // N2 + N2 dissociation data
	arma::vec ddata_N2N = klib::load_dissociation_parameters(N2, N); // N2 + N dissociation data
	arma::mat33 beta_matrix; // the matrix of beta integral brackets
	arma::vec3 right_parts; // the right-hand side of the system
	arma::vec3 results; // the values of the expansion coefficients g_{c,pq} - the order is g_{N2,10}, g_{N2,01}, g_{N,10}

	double R_react_N2, R_react_N; // relaxation terms
	double T, n, rho, omega11_N2N, tau_rot_N2N, tau_rot_N2N2, eta_zeta_N2N2, eta_zeta_N2N, cV, SJsl, PJsl, SJslN2, PJslN2; // the numeric density of the mixture, the density of the mixture, Omega^{(1,1)}_{N2,N}, rotational relaxation times for N2+N and N2+N2, the quantity 4T \pi / (\eta_{cd} * \xi_{cd}), the quantity dE/dT
	double tmp_int00 = 0.0;
	beta_matrix.at(0, 0) = 1.5 * (1. - xN);
	beta_matrix.at(0, 2) = 1.5 * xN; // these appear due to the constraint conditions and are independent of temperature
	beta_matrix.zeros();
	right_parts[0] = 0.;
	for (int i = 0; i < points_amt; i++) {
		T = T_array[i];
		n = p / (KLIB_CONST_K * T);
		N2.renorm(T, xN2 * n);
		rho = xN2 * n * N2.mass + xN * n * N.mass;
		omega11_N2N = klib::omega(T, 1, 1, idata_N2N, "ESA", true, true); // we set nokt to true so that the result is of order 10e-07 instead of 10e-16
		tau_rot_N2N = klib::rot_rel_time_vss(T, idata_N2N, N2, n);
		tau_rot_N2N2 = klib::rot_rel_time_vss(T, idata_N2N2, N2, n);
		eta_zeta_N2N2 = 1. / (n * KLIB_CONST_K * tau_rot_N2N2);
		eta_zeta_N2N = 1. / (n * KLIB_CONST_K * tau_rot_N2N);
		cV = 1.5 * KLIB_CONST_K * n / rho + xN2 * (N2.mass * n / rho) * (N2.crot + N2.E_vibr_dT(T));
		beta_matrix.at(0, 1) = xN2 * klib::wt_poly_norm(T, N2);

		beta_matrix.at(1, 0) = -xN2 * N2.mass * N2.crot * (xN * (0.33333) * eta_zeta_N2N + xN2 * eta_zeta_N2N2); // does vibrational relaxation time play any significant role?
		beta_matrix.at(1, 1) = xN2 * N2.mass * N2.crot * (xN * eta_zeta_N2N + xN2 * eta_zeta_N2N2);
		beta_matrix.at(2, 0) = (2. / 9.) * xN2 * xN * (-16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);
		beta_matrix.at(2, 2) = (2. / 9.) * xN2 * xN * (16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);

		beta_matrix.at(1, 0) /= sqrt(KLIB_CONST_K * T);
		beta_matrix.at(1, 1) /= sqrt(KLIB_CONST_K * T);
		R_react_N2 = -klib::diss_rate_treanor_marrone(T, ddata_N2N, N2) * (xN * n) * (xN2 * n);

		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2; // this is a binary mixture and the relaxation terms are related in a simple way

		SJsl = 0.0;
		PJsl = 0.0;
		SJslN2 = 0.0;
		PJslN2 = 0.0;

		for (int vl = 0; vl <= N2.num_vibr; vl++) {
			tmp_int00 = klib::diss_integral(T, 0, idata_N2N, N2, vl, true, vl_dependent, cs_model, true);
			SJsl += (1. / 3.) * (12 * tmp_int00  - klib::diss_integral(T, 1, idata_N2N, N2, vl, true, true, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJsl += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * 8 * tmp_int00 * N2.vibr_exp(T, vl) / N2.Z_vibr(T);

			tmp_int00 = klib::diss_integral(T, 0, idata_N2N2, N2, vl, true, vl_dependent, cs_model, true);
			SJslN2 += (1. / 2.) * (12 * tmp_int00 - 8 * klib::diss_integral(T, 1, idata_N2N2, N2, vl, true, vl_dependent, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJslN2 += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * 8 * tmp_int00 * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
		}

		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJsl * (xN * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV) - 2 * 1.5 * SJsl * (xN * xN2) * n;
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "\nprel_{N2+N}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);

		R_react_N2 = klib::diss_rate_treanor_marrone(T, ddata_N2N2, N2) * (xN2 * n) * (xN2 * n);
		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2;
		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJslN2 * (xN2 * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV) - 2 * 1.5 * SJslN2 * (xN2 * xN2) * n;
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "; prel_{N2+N2}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);
	}
}
<|endoftext|>


<commit_before>// This file is part of The New Aspell
// Copyright (C) 2001-2003 by Kevin Atkinson under the GNU LGPL license
// version 2.0 or 2.1.  You should have received a copy of the LGPL
// license along with this library if you did not you can find
// it at http://www.gnu.org/.

#ifndef ASPELL_VECTOR__HPP
#define ASPELL_VECTOR__HPP

#include <vector>

namespace acommon
{
  template <typename T>
  class Vector : public std::vector<T>
  {
  public:

    Vector() {}
    Vector(unsigned int s) : std::vector<T>(s) {}
    Vector(unsigned int s, const T & val) : std::vector<T>(s, val) {}

    void append(T t) {
      this->push_back(t);
    }
    void append(const T * begin, unsigned int size) {
      this->insert(this->end(), begin, begin+size);
    }
    void append(const T * begin, const T * end) {
      this->insert(this->end(), begin, end);
    }
    int alloc(int s) {
      int pos = this->size();
      this->resize(pos + s);
      return pos;
    }
    T * data() {return &*this->begin();}
    T * data(int pos) {return &*this->begin() + pos;}
    T * data_end() {return &this->back()+1;}

    T * pbegin() {return &*this->begin();}
    T * pend()   {return &this->back()+1;}

    const T * pbegin() const {return &*this->begin();}
    const T * pend()   const {return &this->back()+1;}

    template <typename U>
    U * datap() {
      return reinterpret_cast<U * >(&this->front());
    }
    template <typename U>
    U * datap(int pos) {
      return reinterpret_cast<U * >(&this->front() + pos);
    }

    void pop_front() {this->erase(this->begin());}
    void push_front(const T & v) {this->insert(this->begin(), v);}
  };
}

#endif
<commit_msg>Avoid calling back() on a empty vector.<commit_after>// This file is part of The New Aspell
// Copyright (C) 2001-2003 by Kevin Atkinson under the GNU LGPL license
// version 2.0 or 2.1.  You should have received a copy of the LGPL
// license along with this library if you did not you can find
// it at http://www.gnu.org/.

#ifndef ASPELL_VECTOR__HPP
#define ASPELL_VECTOR__HPP

#include <vector>

namespace acommon
{
  template <typename T>
  class Vector : public std::vector<T>
  {
  public:

    Vector() {}
    Vector(unsigned int s) : std::vector<T>(s) {}
    Vector(unsigned int s, const T & val) : std::vector<T>(s, val) {}

    void append(T t) {
      this->push_back(t);
    }
    void append(const T * begin, unsigned int size) {
      this->insert(this->end(), begin, begin+size);
    }
    void append(const T * begin, const T * end) {
      this->insert(this->end(), begin, end);
    }
    int alloc(int s) {
      int pos = this->size();
      this->resize(pos + s);
      return pos;
    }
    T * data() {return &*this->begin();}
    T * data(int pos) {return &*this->begin() + pos;}
    T * data_end() {return &*this->begin() + this->size();}

    T * pbegin() {return &*this->begin();}
    T * pend()   {return &*this->begin() + this->size();}

    const T * pbegin() const {return &*this->begin();}
    const T * pend()   const {return &*this->begin() + this->size();}

    template <typename U>
    U * datap() {
      return reinterpret_cast<U * >(&this->front());
    }
    template <typename U>
    U * datap(int pos) {
      return reinterpret_cast<U * >(&this->front() + pos);
    }

    void pop_front() {this->erase(this->begin());}
    void push_front(const T & v) {this->insert(this->begin(), v);}
  };
}

#endif
<|endoftext|>


<commit_before>/**********************************************************************
 *
 *    FILE:            Image.cpp
 *
 *    DESCRIPTION:    Read/Write osg::Image in binary format to disk.
 *
 *    CREATED BY:        Auto generated by iveGenerated
 *                    and later modified by Rune Schmidt Jensen.
 *
 *    HISTORY:        Created 20.3.2003
 *
 *    Copyright 2003 VR-C
 **********************************************************************/

#include "Exception.h"
#include "Image.h"
#include "Object.h"

#include <osg/Notify>

using namespace ive;

void Image::write(DataOutputStream* out)
{
    // Write Image's identification.
    out->writeInt(IVEIMAGE);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj){
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("Image::write(): Could not cast this osg::Image to an osg::Object.");
    // Write Image's properties.

    // Write name
    out->writeString(getFileName());

    // Write width, height, depth of image.
    out->writeInt(s());
    out->writeInt(t());
    out->writeInt(r());

    osg::notify(osg::DEBUG_INFO) << "image written '" << getFileName()<<"'\t"<<s()<<"\t"<<t()<<std::endl;

    // Write formats, type and packing
    out->writeInt(getInternalTextureFormat());
    out->writeInt(getPixelFormat());
    out->writeInt(getDataType());
    out->writeInt(getPacking());

    // Write modified tag.
    out->writeInt(getModifiedTag());

    // Write mipmapdata vector
    int size = _mipmapData.size();
    out->writeInt(size);
    for(int i=0;i<size;i++)
        out->writeInt(_mipmapData[i]);

    // Write image data if any
    out->writeBool(data()!=0);
    if(data())
    {
        // Compute the size of image data and write this.
        unsigned int size = getTotalSizeInBytesIncludingMipmaps();
        out->writeInt(size);
        // Write the data
        out->writeCharArray((char*)data(), size);
    }

}

void Image::read(DataInputStream* in)
{
    // Peek Image's identification.
    int id = in->peekInt();
    if(id == IVEIMAGE){
        // Read Image's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj){
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("Image::read(): Could not cast this osg::Image to an osg::Object.");
        // Read Image's properties.

        // Read name
        setFileName(in->readString());

        // Read width, height, depth of image.
        int is=in->readInt();
        int it=in->readInt();
        int ir=in->readInt();

        // Read formats, type and packing
        GLint internalTextureFormat = (GLint) in->readInt();
        GLenum pixelFormat = (GLenum) in->readInt();
        GLenum dataType = (GLenum) in->readInt();;
        unsigned int packing = (unsigned int)in->readInt();

        // Read modified tag.
        setModifiedTag((unsigned int)in->readInt());

        // Read mipmapdata vector
        int size = in->readInt();
        _mipmapData.resize(size);

        //if (size) std::cout<<"is mip mapped ";

        for(int i=0;i<size;i++)
        {
            _mipmapData[i]=(unsigned int)in->readInt();
            //std::cout<<_mipmapData[i]<<"\t";
        }
        //std::cout<<std::endl;

        // Read image data if any
        if(in->readBool())
        {
            unsigned int dataSize = (unsigned int)in->readInt();

            //static int totalSize = 0;

            //totalSize += dataSize;
            //std::cout<<getFileName()<<" "<<is<<" "<<it<<std::endl;
            //std::cout<<" dataSize = "<<dataSize<<"\tTotalSize = "<<totalSize<<std::endl;

            //char* data = (char*)malloc (dataSize);
            char* data =  new char[dataSize];
            if(!data)
                throw Exception("Image::read(): Unable to allocate memory for image data.");
            in->readCharArray(data,dataSize);
            setImage(is, it, ir, internalTextureFormat, pixelFormat,
                dataType, (unsigned char* ) data, osg::Image::USE_NEW_DELETE, packing);
        }
    }
    else{
        throw Exception("Image::read(): Expected Image identification.");
    }
}
<commit_msg>From Marco Jez, "fixes a bug that prevented mipmaps in images from being read correctly (the call to setImage() clears the previously filled _mipmapData vector)."<commit_after>/**********************************************************************
 *
 *    FILE:            Image.cpp
 *
 *    DESCRIPTION:    Read/Write osg::Image in binary format to disk.
 *
 *    CREATED BY:        Auto generated by iveGenerated
 *                    and later modified by Rune Schmidt Jensen.
 *
 *    HISTORY:        Created 20.3.2003
 *
 *    Copyright 2003 VR-C
 **********************************************************************/

#include "Exception.h"
#include "Image.h"
#include "Object.h"

#include <osg/Notify>

using namespace ive;

void Image::write(DataOutputStream* out)
{
    // Write Image's identification.
    out->writeInt(IVEIMAGE);
    // If the osg class is inherited by any other class we should also write this to file.
    osg::Object*  obj = dynamic_cast<osg::Object*>(this);
    if(obj){
        ((ive::Object*)(obj))->write(out);
    }
    else
        throw Exception("Image::write(): Could not cast this osg::Image to an osg::Object.");
    // Write Image's properties.

    // Write name
    out->writeString(getFileName());

    // Write width, height, depth of image.
    out->writeInt(s());
    out->writeInt(t());
    out->writeInt(r());

    osg::notify(osg::DEBUG_INFO) << "image written '" << getFileName()<<"'\t"<<s()<<"\t"<<t()<<std::endl;

    // Write formats, type and packing
    out->writeInt(getInternalTextureFormat());
    out->writeInt(getPixelFormat());
    out->writeInt(getDataType());
    out->writeInt(getPacking());

    // Write modified tag.
    out->writeInt(getModifiedTag());

    // Write mipmapdata vector
    int size = _mipmapData.size();
    out->writeInt(size);
    for(int i=0;i<size;i++)
        out->writeInt(_mipmapData[i]);

    // Write image data if any
    out->writeBool(data()!=0);
    if(data())
    {
        // Compute the size of image data and write this.
        unsigned int size = getTotalSizeInBytesIncludingMipmaps();
        out->writeInt(size);
        // Write the data
        out->writeCharArray((char*)data(), size);
    }

}

void Image::read(DataInputStream* in)
{
    // Peek Image's identification.
    int id = in->peekInt();
    if(id == IVEIMAGE){
        // Read Image's identification.
        id = in->readInt();
        // If the osg class is inherited by any other class we should also read this from file.
        osg::Object*  obj = dynamic_cast<osg::Object*>(this);
        if(obj){
            ((ive::Object*)(obj))->read(in);
        }
        else
            throw Exception("Image::read(): Could not cast this osg::Image to an osg::Object.");
        // Read Image's properties.

        // Read name
        setFileName(in->readString());

        // Read width, height, depth of image.
        int is=in->readInt();
        int it=in->readInt();
        int ir=in->readInt();

        // Read formats, type and packing
        GLint internalTextureFormat = (GLint) in->readInt();
        GLenum pixelFormat = (GLenum) in->readInt();
        GLenum dataType = (GLenum) in->readInt();;
        unsigned int packing = (unsigned int)in->readInt();

        // Read modified tag.
        setModifiedTag((unsigned int)in->readInt());

        // Read mipmapdata vector
        int size = in->readInt();
        MipmapDataType mipmapData(size);

        //if (size) std::cout<<"is mip mapped ";

        for(int i=0;i<size;i++)
        {
            mipmapData[i]=(unsigned int)in->readInt();
            //std::cout<<_mipmapData[i]<<"\t";
        }
        //std::cout<<std::endl;

        // Read image data if any
        if(in->readBool())
        {
            unsigned int dataSize = (unsigned int)in->readInt();

            //static int totalSize = 0;

            //totalSize += dataSize;
            //std::cout<<getFileName()<<" "<<is<<" "<<it<<std::endl;
            //std::cout<<" dataSize = "<<dataSize<<"\tTotalSize = "<<totalSize<<std::endl;

            //char* data = (char*)malloc (dataSize);
            char* data =  new char[dataSize];
            if(!data)
                throw Exception("Image::read(): Unable to allocate memory for image data.");
            in->readCharArray(data,dataSize);
            setImage(is, it, ir, internalTextureFormat, pixelFormat,
                dataType, (unsigned char* ) data, osg::Image::USE_NEW_DELETE, packing);
        }

        _mipmapData.swap(mipmapData);
    }
    else{
        throw Exception("Image::read(): Expected Image identification.");
    }
}
<|endoftext|>


<commit_before>#if defined(_MSC_VER)
	#pragma warning( disable : 4786 )
#endif

#include "osg/Light"

#include "osgDB/Registry"
#include "osgDB/Input"
#include "osgDB/Output"

using namespace osg;
using namespace osgDB;

// forward declare functions to use later.
bool Light_readLocalData(Object& obj, Input& fr);
bool Light_writeLocalData(const Object& obj, Output& fw);

// register the read and write functions with the osgDB::Registry.
RegisterDotOsgWrapperProxy g_LightProxy
(
    osgNew osg::Light,
    "Light",
    "Object StateAttribute Light",
    &Light_readLocalData,
    &Light_writeLocalData
);

bool Light_readLocalData(Object& obj, Input& fr)
{
    bool iteratorAdvanced = false;

    Light& light = static_cast<Light&>(obj);

    if (fr[0].matchWord("light_num"))
    {
        int lightnum=0;
        if (fr[1].getInt(lightnum))
        {
            light.setLightNum(lightnum);
            fr += 2;
            iteratorAdvanced = true;
        }
    }

#define ReadVec4(A,B) {  \
    if (fr[0].matchWord(B) && \
        fr[1].getFloat(vec4[0]) && \
        fr[2].getFloat(vec4[1]) && \
        fr[3].getFloat(vec4[2]) && \
        fr[4].getFloat(vec4[3])) \
    { \
        light.A(vec4); \
        fr+=5; \
        iteratorAdvanced = true; \
    } \
}

#define ReadVec3(A,B) {  \
    if (fr[0].matchWord(B) && \
        fr[1].getFloat(vec3[0]) && \
        fr[2].getFloat(vec3[1]) && \
        fr[3].getFloat(vec4[2])) \
    { \
        light.A(vec3); \
        fr+=4; \
        iteratorAdvanced = true; \
    } \
}

#define ReadFloat(A,B) {  \
    if (fr[0].matchWord(B) && \
        fr[1].getFloat(value)) \
    { \
        light.A(value); \
        fr+=4; \
        iteratorAdvanced = true; \
    } \
}

    Vec4 vec4;
    ReadVec4(setAmbient,"ambient")
    ReadVec4(setDiffuse,"diffuse")
    ReadVec4(setSpecular,"specular")
    ReadVec4(setPosition,"position")

    Vec3 vec3;
    ReadVec3(setDirection,"direction")

    float value;
    ReadFloat(setConstantAttenuation,"constant_attenuation")
    ReadFloat(setLinearAttenuation,"linear_attenuation")
    ReadFloat(setQuadraticAttenuation,"quadratic_attenuation")
    ReadFloat(setSpotExponent,"spot_exponent")
    ReadFloat(setSpotCutoff,"spot_cutoff")

#undef ReadVec4
#undef ReadVec3
#undef ReadFloat

    return iteratorAdvanced;
}

bool Light_writeLocalData(const Object& obj,Output& fw)
{
    const Light& light = static_cast<const Light&>(obj);

    fw.indent() << "light_num " << light.getLightNum() << std::endl;

    // Vec4's
    fw.indent() << "ambient " << light.getAmbient() << std::endl;
    fw.indent() << "diffuse " << light.getDiffuse() << std::endl;
    fw.indent() << "specular " << light.getSpecular() << std::endl;
    fw.indent() << "position " << light.getPosition() << std::endl;

    // Vec3's
    fw.indent() << "direction " << light.getDirection() << std::endl;

    // float's
    fw.indent() << "constant_attenuation " << light.getConstantAttenuation() << std::endl;
    fw.indent() << "linear_attenuation " << light.getLinearAttenuation () << std::endl;
    fw.indent() << "quadratic_attenuation " << light.getQuadraticAttenuation() << std::endl;
    fw.indent() << "spot_exponent " << light.getSpotExponent() << std::endl;
    fw.indent() << "spot_cutoff " << light.getSpotCutoff() << std::endl;

    return true;
}
<commit_msg>Fixed bug in the Light reading code.<commit_after>#if defined(_MSC_VER)
	#pragma warning( disable : 4786 )
#endif

#include "osg/Light"

#include "osgDB/Registry"
#include "osgDB/Input"
#include "osgDB/Output"

using namespace osg;
using namespace osgDB;

// forward declare functions to use later.
bool Light_readLocalData(Object& obj, Input& fr);
bool Light_writeLocalData(const Object& obj, Output& fw);

// register the read and write functions with the osgDB::Registry.
RegisterDotOsgWrapperProxy g_LightProxy
(
    osgNew osg::Light,
    "Light",
    "Object StateAttribute Light",
    &Light_readLocalData,
    &Light_writeLocalData
);

bool Light_readLocalData(Object& obj, Input& fr)
{
    bool iteratorAdvanced = false;

    Light& light = static_cast<Light&>(obj);

    if (fr[0].matchWord("light_num"))
    {
        int lightnum=0;
        if (fr[1].getInt(lightnum))
        {
            light.setLightNum(lightnum);
            fr += 2;
            iteratorAdvanced = true;
        }
    }

#define ReadVec4(A,B) {  \
    if (fr[0].matchWord(B) && \
        fr[1].getFloat(vec4[0]) && \
        fr[2].getFloat(vec4[1]) && \
        fr[3].getFloat(vec4[2]) && \
        fr[4].getFloat(vec4[3])) \
    { \
        light.A(vec4); \
        fr+=5; \
        iteratorAdvanced = true; \
    } \
}

#define ReadVec3(A,B) {  \
    if (fr[0].matchWord(B) && \
        fr[1].getFloat(vec3[0]) && \
        fr[2].getFloat(vec3[1]) && \
        fr[3].getFloat(vec3[2])) \
    { \
        light.A(vec3); \
        fr+=4; \
        iteratorAdvanced = true; \
    } \
}

#define ReadFloat(A,B) {  \
    if (fr[0].matchWord(B) && \
        fr[1].getFloat(value)) \
    { \
        light.A(value); \
        fr+=2; \
        iteratorAdvanced = true; \
    } \
}

    Vec4 vec4;
    ReadVec4(setAmbient,"ambient")
    ReadVec4(setDiffuse,"diffuse")
    ReadVec4(setSpecular,"specular")
    ReadVec4(setPosition,"position")

    Vec3 vec3;
    ReadVec3(setDirection,"direction")

    float value;
    ReadFloat(setConstantAttenuation,"constant_attenuation")
    ReadFloat(setLinearAttenuation,"linear_attenuation")
    ReadFloat(setQuadraticAttenuation,"quadratic_attenuation")
    ReadFloat(setSpotExponent,"spot_exponent")
    ReadFloat(setSpotCutoff,"spot_cutoff")

#undef ReadVec4
#undef ReadVec3
#undef ReadFloat

    return iteratorAdvanced;
}

bool Light_writeLocalData(const Object& obj,Output& fw)
{
    const Light& light = static_cast<const Light&>(obj);

    fw.indent() << "light_num " << light.getLightNum() << std::endl;

    // Vec4's
    fw.indent() << "ambient " << light.getAmbient() << std::endl;
    fw.indent() << "diffuse " << light.getDiffuse() << std::endl;
    fw.indent() << "specular " << light.getSpecular() << std::endl;
    fw.indent() << "position " << light.getPosition() << std::endl;

    // Vec3's
    fw.indent() << "direction " << light.getDirection() << std::endl;

    // float's
    fw.indent() << "constant_attenuation " << light.getConstantAttenuation() << std::endl;
    fw.indent() << "linear_attenuation " << light.getLinearAttenuation () << std::endl;
    fw.indent() << "quadratic_attenuation " << light.getQuadraticAttenuation() << std::endl;
    fw.indent() << "spot_exponent " << light.getSpotExponent() << std::endl;
    fw.indent() << "spot_cutoff " << light.getSpotCutoff() << std::endl;

    return true;
}
<|endoftext|>