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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    ImageSliceIteratorWithIndex.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/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 notices for more information.

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

// Software Guide : BeginLatex
//
// \index{Iterators!and image slices}
//
// The \code{itk::ImageSliceIteratorWithIndex} is an extension of the
// \code{itk::ImageLinearIteratorWithIndex} from iteration along lines to
// iteration along both lines \emph{and planes} in an image.  A \emph{slice} is a 2D
// plane spanned by two vectors pointing along coordinate axes.  The two
// coordinate directions which define the slice plane are set as member
// variables.
//
// \begin{itemize}
// \index{itk::ImageSliceIteratorWithIndex!SetFirstDirection()}
// \item \textbf{\code{SetFirstDirection()}} Specifies the first coordinate axis
// direction of the slice plane.
//
// \index{itk::ImageSliceIteratorWithIndex!SetSecondDirection()}
// \item \textbf{\code{SetSecondDirection()}} Specifies the second coordinate axis
// direction of the slice plane.
// \end{itemize}
//
// Several new methods control movement from slice to slice.
//
// \begin{itemize}
//
// \index{itk::ImageSliceIteratorWithIndex!NextSlice()}
// \item \textbf{\code{NextSlice()}} Moves the iterator to the beginning pixel
// location of the next slice in the image.  The origin of the next slice is
// calculated by incrementing the current origin index along the fastest
// increasing dimension of the image subspace which excludes the first and
// second dimensions of the iterator.
//
// \index{itk::ImageSliceIteratorWithIndex!PreviousSlice()}
// \item \textbf{\code{PreviousSlice()}} Moves the iterator to the \emph{last
// valid pixel location} in the previous slice.  The origin of the previous
// slice is calculated by decrementing the current origin index along the
// fastest increasing dimension of the image subspace which excludes the first
// and second dimensions of the iterator.
//
// \index{itk::ImageSliceIteratorWithIndex!IsAtBeginOfSlice(})
// \item \textbf{\code{IsAtBeginOfSlice()}} Returns true if the iterator
// points to the beginning pixel of the current slice.
//
// \index{itk::ImageSliceIteratorWithIndex!IsAtEndOfSlice(})
// \item \textbf{\code{IsAtEndOfSlice()}} Returns true if the iterator points
// to \emph{one position past} the last valid pixel of the current slice.
//
// \end{itemize}
//
// The slice iterator moves line by line using \code{NextLine()} and
// \code{PreviousLine()}.  The line direction is parallel to the \emph{second}
// coordinate axis direction of the slice plane (see also
// section~\ref{sec:itkImageLinearIteratorWithIndex}).
//
// \index{itk::ImageSliceIteratorWithIndex!example of using|(}
// The next code example calculates the maximum intensity projection along one
// of the coordinate axes of an image volume.  The algorithm is straightforward
// using \code{itk::ImageSliceIteratorWithIndex} because we can coordinate
// movement through a slice of the 3D input image with movement through the 2D
// planar output.
//
// Here is how the algorithm works.  For each 2D slice of the input, iterate
// through all the pixels line by line. Copy a pixel value to the corresponding
// position in the 2D output image if it is larger than the value already
// contained there.  When all slices have been processed, the output image is
// the desired maximum intensity projection.
//
// We include a header for the const version of the slice iterator. For writing
// values to the 2D projection image, we use the linear iterator from the
// previous section.  The linear iterator is chosen because it can be set to
// follow the same path in its underlying 2D image that the slice iterator
// follows over each slice of the 3D image.
//
// Software Guide : EndLatex

#include "itkImage.h"
#include "vnl/vnl_math.h"

// Software Guide : BeginCodeSnippet
#include "itkImageSliceConstIteratorWithIndex.h"
#include "itkImageLinearIteratorWithIndex.h"
// Software Guide : EndCodeSnippet
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

int main( int argc, char ** argv )
{
  //   Verify the number of parameters on the command line.
  if ( argc < 4 )
    {
      std::cerr << "Missing parameters. " << std::endl;
      std::cerr << "Usage: " << std::endl;
      std::cerr << argv[0]
                << " inputImageFile outputImageFile projectionDirection"
                << std::endl;
      return -1;
    }

// Software Guide : BeginLatex
//
// The pixel type is defined as unsigned short.  For this application, we need
// two image types, a 3D image for the input, and a 2D image for the intensity
// projection.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef unsigned short PixelType;
  typedef itk::Image< PixelType, 2 >  ImageType2D;
  typedef itk::Image< PixelType, 3 >  ImageType3D;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
//  A slice iterator type is defined to walk the input image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::ImageLinearIteratorWithIndex< ImageType2D > LinearIteratorType;
  typedef itk::ImageSliceConstIteratorWithIndex< ImageType3D >  SliceIteratorType;
// Software Guide : EndCodeSnippet

  typedef itk::ImageFileReader< ImageType3D > ReaderType;
  typedef itk::ImageFileWriter< ImageType2D > WriterType;

  ImageType3D::ConstPointer inputImage;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
  try
    {
      reader->Update();
      inputImage = reader->GetOutput();
    }
  catch ( itk::ExceptionObject &err)
    {
      std::cout << "ExceptionObject caught !" << std::endl;
      std::cout << err << std::endl;
      return -1;
    }

// Software Guide : BeginLatex
//
// The projection direction is read from the command line. The projection image
// will be the size of the 2D plane orthogonal to the projection direction.
// Its spanning vectors are the two remaining coordinate axes in the volume.
// These axes are recorded in the \code{direction} array.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  unsigned int projectionDirection = static_cast<unsigned int>( ::atoi( argv[3] ) );

  unsigned int i, j;
  unsigned int direction[2];
  for (i = 0, j = 0; i < 3; ++i )
    {
      if (i != projectionDirection)
        {
          direction[j] = i;
          j++;
        }
    }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// The \code{direction} array is now used to define the projection image size
// based on the input image size.  The output image is created so that its
// common dimension(s) with the input image are the same size.  For example, if
// we project along the X axis of the input, the size and origin of the Y axes
// of the input and output will match.  This makes the code slightly more
// complicated, but prevents a counter-intuitive rotation of the output.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  ImageType2D::RegionType region;
  ImageType2D::RegionType::SizeType size;
  ImageType2D::RegionType::IndexType index;

  index[ direction[0] ] = inputImage->GetRequestedRegion().GetIndex()[ direction[0] ];
  index[ 1- direction[0] ] = inputImage->GetRequestedRegion().GetIndex()[ direction[1] ];
  size[ direction[0] ] = inputImage->GetRequestedRegion().GetSize()[ direction[0] ];
  size[ 1- direction[0] ] = inputImage->GetRequestedRegion().GetSize()[ direction[1] ];

  region.SetSize( size );
  region.SetIndex( index );

  ImageType2D::Pointer outputImage = ImageType2D::New();
  outputImage->SetRegions( region );
  outputImage->Allocate();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Next we create the necessary iterators.  The const slice iterator walks the 3D input image,
// and the non-const linear iterator walks the 2D output image. The iterators are
// initialized to walk the same linear path through a slice.  Remember that the
// \emph{second} direction of the slice iterator defines the direction linear
// iteration walks within a slice.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  SliceIteratorType  inputIt(  inputImage,  inputImage->GetRequestedRegion() );
  LinearIteratorType outputIt( outputImage, outputImage->GetRequestedRegion() );

  inputIt.SetFirstDirection(  direction[1] );
  inputIt.SetSecondDirection( direction[0] );

  outputIt.SetDirection( 1 - direction[0] );
// Software Guide : EndCodeSnippet

// Software Guide: BeginLatex
//
// Now we are ready to compute the projection.  The first step is to initialize
// all of the projection values to their nonpositive minimum value.  The
// projection values are then updated row by row from the first slice of the
// input.  At the end of the first slice, the input iterator steps to the first
// row in the next slice, while the output iterator, whose underlying image
// consists of only one slice, rewinds to its first row.  The process repeats
// until the last slice of the input is processed.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  outputIt.GoToBegin();
  while ( ! outputIt.IsAtEnd() )
    {
      while ( ! outputIt.IsAtEndOfLine() )
        {
          outputIt.Set( itk::NumericTraits<unsigned short>::NonpositiveMin() );
          ++outputIt;
        }
      outputIt.NextLine();
    }

  inputIt.GoToBegin();
  outputIt.GoToBegin();

  while( !inputIt.IsAtEnd() )
    {
      while ( !inputIt.IsAtEndOfSlice() )
        {
          while ( !inputIt.IsAtEndOfLine() )
            {
              outputIt.Set( vnl_math_max( outputIt.Get(), inputIt.Get() ));
              ++inputIt;
              ++outputIt;
            }
          outputIt.NextLine();
          inputIt.NextLine();

        }
      outputIt.GoToBegin();
      inputIt.NextSlice();
    }
  // Software Guide : EndCodeSnippet

  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( argv[2] );
  writer->SetInput(outputImage);
  try
    {
      writer->Update();
    }
  catch ( itk::ExceptionObject &err)
    {
      std::cout << "ExceptionObject caught !" << std::endl;
      std::cout << err << std::endl;
      return -1;
}

// Software Guide : BeginLatex
//
// Running this example code on the 3D image
// Insight/Examples/Data/BrainProtonDensity3Slices.mha using the $z$-axis as
// the axis of projection gives the image shown in
// figure~\ref{fig:ImageSliceIteratorWithIndexOutput}.
//
// \begin{figure}
// \centering
// \includegraphics[width=0.4\textwidth]{ImageSliceIteratorWithIndexOutput.eps}
// \caption[Maximum intensity projection using ImageSliceIteratorWithIndex]{The
// maximum intensity projection through three slices of a volume..}
// \protect\label{fig:ImageSliceIteratorWithIndexOutput}
// \end{figure}
//
//
// \index{itk::ImageSliceIteratorWithIndex!example of using|)}
//
// Software Guide : EndLatex

  return 0;
}
<commit_msg>DOC: \doxygen{} keyword used for adding hyperlinks to ITK classes man pages.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    ImageSliceIteratorWithIndex.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/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 notices for more information.

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

// Software Guide : BeginLatex
//
// \index{Iterators!and image slices}
//
// The \doxygen{ImageSliceIteratorWithIndex} is an extension of the
// \doxygen{ImageLinearIteratorWithIndex} from iteration along lines to
// iteration along both lines \emph{and planes} in an image.  A \emph{slice} is a 2D
// plane spanned by two vectors pointing along coordinate axes.  The two
// coordinate directions which define the slice plane are set as member
// variables.
//
// \begin{itemize}
// \index{itk::ImageSliceIteratorWithIndex!SetFirstDirection()}
// \item \textbf{\code{SetFirstDirection()}} Specifies the first coordinate axis
// direction of the slice plane.
//
// \index{itk::ImageSliceIteratorWithIndex!SetSecondDirection()}
// \item \textbf{\code{SetSecondDirection()}} Specifies the second coordinate axis
// direction of the slice plane.
// \end{itemize}
//
// Several new methods control movement from slice to slice.
//
// \begin{itemize}
//
// \index{itk::ImageSliceIteratorWithIndex!NextSlice()}
// \item \textbf{\code{NextSlice()}} Moves the iterator to the beginning pixel
// location of the next slice in the image.  The origin of the next slice is
// calculated by incrementing the current origin index along the fastest
// increasing dimension of the image subspace which excludes the first and
// second dimensions of the iterator.
//
// \index{itk::ImageSliceIteratorWithIndex!PreviousSlice()}
// \item \textbf{\code{PreviousSlice()}} Moves the iterator to the \emph{last
// valid pixel location} in the previous slice.  The origin of the previous
// slice is calculated by decrementing the current origin index along the
// fastest increasing dimension of the image subspace which excludes the first
// and second dimensions of the iterator.
//
// \index{itk::ImageSliceIteratorWithIndex!IsAtBeginOfSlice()}
// \item \textbf{\code{IsAtBeginOfSlice()}} Returns true if the iterator
// points to the beginning pixel of the current slice.
//
// \index{itk::ImageSliceIteratorWithIndex!IsAtEndOfSlice()}
// \item \textbf{\code{IsAtEndOfSlice()}} Returns true if the iterator points
// to \emph{one position past} the last valid pixel of the current slice.
//
// \end{itemize}
//
// The slice iterator moves line by line using \code{NextLine()} and
// \code{PreviousLine()}.  The line direction is parallel to the \emph{second}
// coordinate axis direction of the slice plane (see also
// section~\ref{sec:itkImageLinearIteratorWithIndex}).
//
// \index{itk::ImageSliceIteratorWithIndex!example of using|(}
// The next code example calculates the maximum intensity projection along one
// of the coordinate axes of an image volume.  The algorithm is straightforward
// using \doxygen{ImageSliceIteratorWithIndex} because we can coordinate
// movement through a slice of the 3D input image with movement through the 2D
// planar output.
//
// Here is how the algorithm works.  For each 2D slice of the input, iterate
// through all the pixels line by line. Copy a pixel value to the corresponding
// position in the 2D output image if it is larger than the value already
// contained there.  When all slices have been processed, the output image is
// the desired maximum intensity projection.
//
// We include a header for the const version of the slice iterator. For writing
// values to the 2D projection image, we use the linear iterator from the
// previous section.  The linear iterator is chosen because it can be set to
// follow the same path in its underlying 2D image that the slice iterator
// follows over each slice of the 3D image.
//
// Software Guide : EndLatex

#include "itkImage.h"
#include "vnl/vnl_math.h"

// Software Guide : BeginCodeSnippet
#include "itkImageSliceConstIteratorWithIndex.h"
#include "itkImageLinearIteratorWithIndex.h"
// Software Guide : EndCodeSnippet
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

int main( int argc, char ** argv )
{
  //   Verify the number of parameters on the command line.
  if ( argc < 4 )
    {
      std::cerr << "Missing parameters. " << std::endl;
      std::cerr << "Usage: " << std::endl;
      std::cerr << argv[0]
                << " inputImageFile outputImageFile projectionDirection"
                << std::endl;
      return -1;
    }

// Software Guide : BeginLatex
//
// The pixel type is defined as unsigned short.  For this application, we need
// two image types, a 3D image for the input, and a 2D image for the intensity
// projection.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef unsigned short PixelType;
  typedef itk::Image< PixelType, 2 >  ImageType2D;
  typedef itk::Image< PixelType, 3 >  ImageType3D;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
//  A slice iterator type is defined to walk the input image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::ImageLinearIteratorWithIndex< ImageType2D > LinearIteratorType;
  typedef itk::ImageSliceConstIteratorWithIndex< ImageType3D >  SliceIteratorType;
// Software Guide : EndCodeSnippet

  typedef itk::ImageFileReader< ImageType3D > ReaderType;
  typedef itk::ImageFileWriter< ImageType2D > WriterType;

  ImageType3D::ConstPointer inputImage;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
  try
    {
      reader->Update();
      inputImage = reader->GetOutput();
    }
  catch ( itk::ExceptionObject &err)
    {
      std::cout << "ExceptionObject caught !" << std::endl;
      std::cout << err << std::endl;
      return -1;
    }

// Software Guide : BeginLatex
//
// The projection direction is read from the command line. The projection image
// will be the size of the 2D plane orthogonal to the projection direction.
// Its spanning vectors are the two remaining coordinate axes in the volume.
// These axes are recorded in the \code{direction} array.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  unsigned int projectionDirection = static_cast<unsigned int>( ::atoi( argv[3] ) );

  unsigned int i, j;
  unsigned int direction[2];
  for (i = 0, j = 0; i < 3; ++i )
    {
      if (i != projectionDirection)
        {
          direction[j] = i;
          j++;
        }
    }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// The \code{direction} array is now used to define the projection image size
// based on the input image size.  The output image is created so that its
// common dimension(s) with the input image are the same size.  For example, if
// we project along the X axis of the input, the size and origin of the Y axes
// of the input and output will match.  This makes the code slightly more
// complicated, but prevents a counter-intuitive rotation of the output.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  ImageType2D::RegionType region;
  ImageType2D::RegionType::SizeType size;
  ImageType2D::RegionType::IndexType index;

  index[ direction[0] ] = inputImage->GetRequestedRegion().GetIndex()[ direction[0] ];
  index[ 1- direction[0] ] = inputImage->GetRequestedRegion().GetIndex()[ direction[1] ];
  size[ direction[0] ] = inputImage->GetRequestedRegion().GetSize()[ direction[0] ];
  size[ 1- direction[0] ] = inputImage->GetRequestedRegion().GetSize()[ direction[1] ];

  region.SetSize( size );
  region.SetIndex( index );

  ImageType2D::Pointer outputImage = ImageType2D::New();
  outputImage->SetRegions( region );
  outputImage->Allocate();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Next we create the necessary iterators.  The const slice iterator walks the 3D input image,
// and the non-const linear iterator walks the 2D output image. The iterators are
// initialized to walk the same linear path through a slice.  Remember that the
// \emph{second} direction of the slice iterator defines the direction linear
// iteration walks within a slice.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  SliceIteratorType  inputIt(  inputImage,  inputImage->GetRequestedRegion() );
  LinearIteratorType outputIt( outputImage, outputImage->GetRequestedRegion() );

  inputIt.SetFirstDirection(  direction[1] );
  inputIt.SetSecondDirection( direction[0] );

  outputIt.SetDirection( 1 - direction[0] );
// Software Guide : EndCodeSnippet

// Software Guide: BeginLatex
//
// Now we are ready to compute the projection.  The first step is to initialize
// all of the projection values to their nonpositive minimum value.  The
// projection values are then updated row by row from the first slice of the
// input.  At the end of the first slice, the input iterator steps to the first
// row in the next slice, while the output iterator, whose underlying image
// consists of only one slice, rewinds to its first row.  The process repeats
// until the last slice of the input is processed.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  outputIt.GoToBegin();
  while ( ! outputIt.IsAtEnd() )
    {
      while ( ! outputIt.IsAtEndOfLine() )
        {
          outputIt.Set( itk::NumericTraits<unsigned short>::NonpositiveMin() );
          ++outputIt;
        }
      outputIt.NextLine();
    }

  inputIt.GoToBegin();
  outputIt.GoToBegin();

  while( !inputIt.IsAtEnd() )
    {
      while ( !inputIt.IsAtEndOfSlice() )
        {
          while ( !inputIt.IsAtEndOfLine() )
            {
              outputIt.Set( vnl_math_max( outputIt.Get(), inputIt.Get() ));
              ++inputIt;
              ++outputIt;
            }
          outputIt.NextLine();
          inputIt.NextLine();

        }
      outputIt.GoToBegin();
      inputIt.NextSlice();
    }
  // Software Guide : EndCodeSnippet

  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( argv[2] );
  writer->SetInput(outputImage);
  try
    {
      writer->Update();
    }
  catch ( itk::ExceptionObject &err)
    {
      std::cout << "ExceptionObject caught !" << std::endl;
      std::cout << err << std::endl;
      return -1;
}

// Software Guide : BeginLatex
//
// Running this example code on the 3D image
// Insight/Examples/Data/BrainProtonDensity3Slices.mha using the $z$-axis as
// the axis of projection gives the image shown in
// figure~\ref{fig:ImageSliceIteratorWithIndexOutput}.
//
// \begin{figure}
// \centering
// \includegraphics[width=0.4\textwidth]{ImageSliceIteratorWithIndexOutput.eps}
// \caption[Maximum intensity projection using ImageSliceIteratorWithIndex]{The
// maximum intensity projection through three slices of a volume..}
// \protect\label{fig:ImageSliceIteratorWithIndexOutput}
// \end{figure}
//
//
// \index{itk::ImageSliceIteratorWithIndex!example of using|)}
//
// Software Guide : EndLatex

  return 0;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkInformationExecutivePortVectorKey.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 "vtkInformationExecutivePortVectorKey.h"

#include "vtkExecutive.h"
#include "vtkGarbageCollector.h"
#include "vtkInformation.h"

#include <vtkstd/algorithm>
#include <vtkstd/vector>

// should the pipeline be double or singly linked (referenced) list, single
// make garbage collecting easier but results in a weak reference.
#define VTK_USE_SINGLE_REF 1

vtkCxxRevisionMacro(vtkInformationExecutivePortVectorKey, "1.7");

//----------------------------------------------------------------------------
vtkInformationExecutivePortVectorKey::vtkInformationExecutivePortVectorKey(const char* name, const char* location):
  vtkInformationKey(name, location)
{
  vtkFilteringInformationKeyManager::Register(this);
}

//----------------------------------------------------------------------------
vtkInformationExecutivePortVectorKey::~vtkInformationExecutivePortVectorKey()
{
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

//----------------------------------------------------------------------------
class vtkInformationExecutivePortVectorValue: public vtkObjectBase
{
public:
  vtkTypeMacro(vtkInformationExecutivePortVectorValue, vtkObjectBase);
  vtkstd::vector<vtkExecutive*> Executives;
  vtkstd::vector<int> Ports;

  virtual ~vtkInformationExecutivePortVectorValue();
  void UnRegisterAllExecutives();
};

//----------------------------------------------------------------------------
vtkInformationExecutivePortVectorValue
::~vtkInformationExecutivePortVectorValue()
{
  // Remove all our references to executives before erasing the vector.
  this->UnRegisterAllExecutives();
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorValue::UnRegisterAllExecutives()
{
#ifndef VTK_USE_SINGLE_REF
  for(vtkstd::vector<vtkExecutive*>::iterator i = this->Executives.begin();
      i != this->Executives.end(); ++i)
    {
    if(vtkExecutive* e = *i)
      {
      e->UnRegister(0);
      }
    }
#endif
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Append(vtkInformation* info,
                                                  vtkExecutive* executive,
                                                  int port)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    // The entry already exists.  Append to its vector.
#ifndef VTK_USE_SINGLE_REF
    executive->Register(0);
#endif
    v->Executives.push_back(executive);
    v->Ports.push_back(port);
    }
  else
    {
    // The entry does not yet exist.  Just create it.
    this->Set(info, &executive, &port, 1);
    }
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Remove(vtkInformation* info,
                                                  vtkExecutive* executive,
                                                  int port)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    // The entry exists.  Find this executive/port pair and remove it.
    for(unsigned int i=0; i < v->Executives.size(); ++i)
      {
      if(v->Executives[i] == executive && v->Ports[i] == port)
        {
        v->Executives.erase(v->Executives.begin()+i);
        v->Ports.erase(v->Ports.begin()+i);
#ifndef VTK_USE_SINGLE_REF
        executive->UnRegister(0);
#endif
        break;
        }
      }

    // If the last entry was removed, remove the entire value.
    if(v->Executives.empty())
      {
      this->SetAsObjectBase(info, 0);
      }
    }
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Set(vtkInformation* info,
                                               vtkExecutive** executives,
                                               int* ports, int length)
{
  if(executives && ports && length > 0)
    {
#ifndef VTK_USE_SINGLE_REF
    // Register our references to all the given executives.
    for(int i=0; i < length; ++i)
      {
      if(executives[i])
        {
        executives[i]->Register(0);
        }
      }
#endif
    // Store the vector of pointers.
    vtkInformationExecutivePortVectorValue* oldv =
      static_cast<vtkInformationExecutivePortVectorValue *>
      (this->GetAsObjectBase(info));
    if(oldv && static_cast<int>(oldv->Executives.size()) == length)
      {
      // Replace the existing value.
      oldv->UnRegisterAllExecutives();
      vtkstd::copy(executives, executives+length, oldv->Executives.begin());
      vtkstd::copy(ports, ports+length, oldv->Ports.begin());
      // Since this sets a value without call SetAsObjectBase(),
      // the info has to be modified here (instead of
      // vtkInformation::SetAsObjectBase()
      info->Modified();
      }
    else
      {
      // Allocate a new value.
      vtkInformationExecutivePortVectorValue* v =
        new vtkInformationExecutivePortVectorValue;
      this->ConstructClass("vtkInformationExecutivePortVectorValue");
      v->Executives.insert(v->Executives.begin(), executives, executives+length);
      v->Ports.insert(v->Ports.begin(), ports, ports+length);
      this->SetAsObjectBase(info, v);
      v->Delete();
      }
    }
  else
    {
    this->SetAsObjectBase(info, 0);
    }
}

//----------------------------------------------------------------------------
vtkExecutive**
vtkInformationExecutivePortVectorKey::GetExecutives(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue *>
    (this->GetAsObjectBase(info));
  return v?(&v->Executives[0]):0;
}

//----------------------------------------------------------------------------
int* vtkInformationExecutivePortVectorKey::GetPorts(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue *>
    (this->GetAsObjectBase(info));
  return v?(&v->Ports[0]):0;
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Get(vtkInformation* info,
                                               vtkExecutive** executives,
                                               int* ports)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    vtkstd::copy(v->Executives.begin(), v->Executives.end(), executives);
    vtkstd::copy(v->Ports.begin(), v->Ports.end(), ports);
    }
}

//----------------------------------------------------------------------------
int vtkInformationExecutivePortVectorKey::Length(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue *>
    (this->GetAsObjectBase(info));
  return v?static_cast<int>(v->Executives.size()):0;
}

//----------------------------------------------------------------------------
int vtkInformationExecutivePortVectorKey::Has(vtkInformation* info)
{
  return this->GetAsObjectBase(info)?1:0;
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::ShallowCopy(vtkInformation* from,
                                                vtkInformation* to)
{
  this->Set(to, this->GetExecutives(from), this->GetPorts(from),
            this->Length(from));
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Remove(vtkInformation* info)
{
  this->Superclass::Remove(info);
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Print(ostream& os,
                                                 vtkInformation* info)
{
  // Print the value.
  if(this->Has(info))
    {
    vtkExecutive** executives = this->GetExecutives(info);
    int* ports = this->GetPorts(info);
    int length = this->Length(info);
    const char* sep = "";
    for(int i=0; i < length; ++i)
      {
      if(executives[i])
        {
        os << sep << executives[i]->GetClassName()
           << "(" << executives[i] << ") port " << ports[i];
        }
      else
        {
        os << sep << "(NULL) port " << ports[i];
        }
      sep = ", ";
      }
    }
}

//----------------------------------------------------------------------------
void
#ifdef VTK_USE_SINGLE_REF
vtkInformationExecutivePortVectorKey::Report(vtkInformation*,
                                             vtkGarbageCollector*)
{
#else
vtkInformationExecutivePortVectorKey::Report(vtkInformation* info,
                                             vtkGarbageCollector* collector)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    for(vtkstd::vector<vtkExecutive*>::iterator i = v->Executives.begin();
        i != v->Executives.end(); ++i)
      {
      vtkGarbageCollectorReport(collector, *i, this->GetName());
      }
    }
#endif
}

//----------------------------------------------------------------------------
vtkExecutive**
vtkInformationExecutivePortVectorKey
::GetExecutivesWatchAddress(vtkInformation* info)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    return &v->Executives[0];
    }
  return 0;
}

//----------------------------------------------------------------------------
int*
vtkInformationExecutivePortVectorKey
::GetPortsWatchAddress(vtkInformation* info)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    return &v->Ports[0];
    }
  return 0;
}
<commit_msg>ENH: Merge changes from main tree into VTK-5-0 branch. (cvs -q up -j1.7 -j1.8 Filtering/vtkInformationExecutivePortVectorKey.cxx)<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkInformationExecutivePortVectorKey.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 "vtkInformationExecutivePortVectorKey.h"

#include "vtkExecutive.h"
#include "vtkGarbageCollector.h"
#include "vtkInformation.h"

#include <vtkstd/algorithm>
#include <vtkstd/vector>

// should the pipeline be double or singly linked (referenced) list, single
// make garbage collecting easier but results in a weak reference.
#define VTK_USE_SINGLE_REF 1

vtkCxxRevisionMacro(vtkInformationExecutivePortVectorKey, "1.7.4.1");

//----------------------------------------------------------------------------
vtkInformationExecutivePortVectorKey::vtkInformationExecutivePortVectorKey(const char* name, const char* location):
  vtkInformationKey(name, location)
{
  vtkFilteringInformationKeyManager::Register(this);
}

//----------------------------------------------------------------------------
vtkInformationExecutivePortVectorKey::~vtkInformationExecutivePortVectorKey()
{
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

//----------------------------------------------------------------------------
class vtkInformationExecutivePortVectorValue: public vtkObjectBase
{
public:
  vtkTypeMacro(vtkInformationExecutivePortVectorValue, vtkObjectBase);
  vtkstd::vector<vtkExecutive*> Executives;
  vtkstd::vector<int> Ports;

  virtual ~vtkInformationExecutivePortVectorValue();
  void UnRegisterAllExecutives();
};

//----------------------------------------------------------------------------
vtkInformationExecutivePortVectorValue
::~vtkInformationExecutivePortVectorValue()
{
  // Remove all our references to executives before erasing the vector.
  this->UnRegisterAllExecutives();
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorValue::UnRegisterAllExecutives()
{
#ifndef VTK_USE_SINGLE_REF
  for(vtkstd::vector<vtkExecutive*>::iterator i = this->Executives.begin();
      i != this->Executives.end(); ++i)
    {
    if(vtkExecutive* e = *i)
      {
      e->UnRegister(0);
      }
    }
#endif
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Append(vtkInformation* info,
                                                  vtkExecutive* executive,
                                                  int port)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    // The entry already exists.  Append to its vector.
#ifndef VTK_USE_SINGLE_REF
    executive->Register(0);
#endif
    v->Executives.push_back(executive);
    v->Ports.push_back(port);
    }
  else
    {
    // The entry does not yet exist.  Just create it.
    this->Set(info, &executive, &port, 1);
    }
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Remove(vtkInformation* info,
                                                  vtkExecutive* executive,
                                                  int port)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    // The entry exists.  Find this executive/port pair and remove it.
    for(unsigned int i=0; i < v->Executives.size(); ++i)
      {
      if(v->Executives[i] == executive && v->Ports[i] == port)
        {
        v->Executives.erase(v->Executives.begin()+i);
        v->Ports.erase(v->Ports.begin()+i);
#ifndef VTK_USE_SINGLE_REF
        executive->UnRegister(0);
#endif
        break;
        }
      }

    // If the last entry was removed, remove the entire value.
    if(v->Executives.empty())
      {
      this->SetAsObjectBase(info, 0);
      }
    }
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Set(vtkInformation* info,
                                               vtkExecutive** executives,
                                               int* ports, int length)
{
  if(executives && ports && length > 0)
    {
#ifndef VTK_USE_SINGLE_REF
    // Register our references to all the given executives.
    for(int i=0; i < length; ++i)
      {
      if(executives[i])
        {
        executives[i]->Register(0);
        }
      }
#endif
    // Store the vector of pointers.
    vtkInformationExecutivePortVectorValue* oldv =
      static_cast<vtkInformationExecutivePortVectorValue *>
      (this->GetAsObjectBase(info));
    if(oldv && static_cast<int>(oldv->Executives.size()) == length)
      {
      // Replace the existing value.
      oldv->UnRegisterAllExecutives();
      vtkstd::copy(executives, executives+length, oldv->Executives.begin());
      vtkstd::copy(ports, ports+length, oldv->Ports.begin());
      // Since this sets a value without call SetAsObjectBase(),
      // the info has to be modified here (instead of
      // vtkInformation::SetAsObjectBase()
      info->Modified();
      }
    else
      {
      // Allocate a new value.
      vtkInformationExecutivePortVectorValue* v =
        new vtkInformationExecutivePortVectorValue;
      this->ConstructClass("vtkInformationExecutivePortVectorValue");
      v->Executives.insert(v->Executives.begin(), executives, executives+length);
      v->Ports.insert(v->Ports.begin(), ports, ports+length);
      this->SetAsObjectBase(info, v);
      v->Delete();
      }
    }
  else
    {
    this->SetAsObjectBase(info, 0);
    }
}

//----------------------------------------------------------------------------
vtkExecutive**
vtkInformationExecutivePortVectorKey::GetExecutives(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue *>
    (this->GetAsObjectBase(info));
  return (v && !v->Executives.empty())?(&v->Executives[0]):0;
}

//----------------------------------------------------------------------------
int* vtkInformationExecutivePortVectorKey::GetPorts(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue *>
    (this->GetAsObjectBase(info));
  return (v && !v->Ports.empty())?(&v->Ports[0]):0;
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Get(vtkInformation* info,
                                               vtkExecutive** executives,
                                               int* ports)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    vtkstd::copy(v->Executives.begin(), v->Executives.end(), executives);
    vtkstd::copy(v->Ports.begin(), v->Ports.end(), ports);
    }
}

//----------------------------------------------------------------------------
int vtkInformationExecutivePortVectorKey::Length(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue *>
    (this->GetAsObjectBase(info));
  return v?static_cast<int>(v->Executives.size()):0;
}

//----------------------------------------------------------------------------
int vtkInformationExecutivePortVectorKey::Has(vtkInformation* info)
{
  return this->GetAsObjectBase(info)?1:0;
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::ShallowCopy(vtkInformation* from,
                                                vtkInformation* to)
{
  this->Set(to, this->GetExecutives(from), this->GetPorts(from),
            this->Length(from));
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Remove(vtkInformation* info)
{
  this->Superclass::Remove(info);
}

//----------------------------------------------------------------------------
void vtkInformationExecutivePortVectorKey::Print(ostream& os,
                                                 vtkInformation* info)
{
  // Print the value.
  if(this->Has(info))
    {
    vtkExecutive** executives = this->GetExecutives(info);
    int* ports = this->GetPorts(info);
    int length = this->Length(info);
    const char* sep = "";
    for(int i=0; i < length; ++i)
      {
      if(executives[i])
        {
        os << sep << executives[i]->GetClassName()
           << "(" << executives[i] << ") port " << ports[i];
        }
      else
        {
        os << sep << "(NULL) port " << ports[i];
        }
      sep = ", ";
      }
    }
}

//----------------------------------------------------------------------------
void
#ifdef VTK_USE_SINGLE_REF
vtkInformationExecutivePortVectorKey::Report(vtkInformation*,
                                             vtkGarbageCollector*)
{
#else
vtkInformationExecutivePortVectorKey::Report(vtkInformation* info,
                                             vtkGarbageCollector* collector)
{
  if(vtkInformationExecutivePortVectorValue* v =
     static_cast<vtkInformationExecutivePortVectorValue *>
     (this->GetAsObjectBase(info)))
    {
    for(vtkstd::vector<vtkExecutive*>::iterator i = v->Executives.begin();
        i != v->Executives.end(); ++i)
      {
      vtkGarbageCollectorReport(collector, *i, this->GetName());
      }
    }
#endif
}

//----------------------------------------------------------------------------
vtkExecutive**
vtkInformationExecutivePortVectorKey
::GetExecutivesWatchAddress(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue*>
    (this->GetAsObjectBase(info));
  return (v && !v->Executives.empty())?(&v->Executives[0]):0;
}

//----------------------------------------------------------------------------
int*
vtkInformationExecutivePortVectorKey
::GetPortsWatchAddress(vtkInformation* info)
{
  vtkInformationExecutivePortVectorValue* v =
    static_cast<vtkInformationExecutivePortVectorValue*>
    (this->GetAsObjectBase(info));
  return (v && !v->Ports.empty())?(&v->Ports[0]):0;
}
<|endoftext|>


<commit_before>#include <memory>

#include "drake/Path.h"
#include "drake/systems/plants/RigidBodyTree.h"

#include "gtest/gtest.h"
#include "gmock/gmock.h"

namespace drake {
namespace systems {
namespace plants {
namespace test {
namespace rigid_body_tree {
namespace {

using Eigen::Vector3d;
using Eigen::VectorXd;
using Eigen::Matrix3Xd;

// Structure used to hold the analytical solution of the tests.
// It stores the collision point on the surface of a collision body in both
// world and body frames.
// See systems/plants/collision/test/model_test.cc.
struct SurfacePoint {
  SurfacePoint() { }
  SurfacePoint(Vector3d wf, Vector3d bf) : world_frame(wf), body_frame(bf) { }
  // Eigen variables are left uninitalized by default.
  Vector3d world_frame;
  Vector3d body_frame;
};

// Solutions are accessed by rigid body pointer using an std::unordered_map.
// DrakeCollision::Model returns the collision detection results as a vector of
// DrakeCollision::PointPair entries. Each entry holds a reference to the pair
// of collision elements taking part in the collision.
// To provide a simple access to the appropriate solution for the collision
// point on each body, a map is used to allow referencing the corresponding
// solution by body pointer.
typedef std::unordered_map<const RigidBody*, SurfacePoint>
    BodyToSurfacePointMap;

class RBTCollisionTest: public ::testing::Test {
 protected:
  void SetUp() override {
    tree_.addRobotFromSDF(
        Drake::getDrakePath() +
        "/systems/plants/test/rigid_body_tree/small_sphere_on_large_box.sdf",
        DrakeJoint::QUATERNION);

    small_sphere_ = tree_.FindBody("small_sphere");
    large_box_ = tree_.FindBody("large_box");

    // Access the analytical solution to the contact point on the surface of
    // each collision element by element id.
    // Solutions are expressed in world and body frames.
    solution_ = {
        /*              world frame    , body frame  */
        {large_box_,    {{0.0, 5.0, 0.0}, {0.0, 2.5, 0.0}}},
        {small_sphere_, {{0.0, 4.9, 0.0}, {0.0, 0.0, 0.6}}}};
  }

  double tolerance_;
  RigidBodyTree tree_;
  const RigidBody *small_sphere_, *large_box_;
  BodyToSurfacePointMap solution_;
};

// This unit test assesses the correct return from
// RigidBodyTree::ComputeMaximumDepthCollisionPoints.
// The test consists on finding the maximum depth penetration point between a
// sphere and a box.
TEST_F(RBTCollisionTest, FindAndComputeContactPoints) {
  // Numerical precision tolerance to perform floating point comparisons.
  // Its magnitude was chosen to be the minimum value for which these tests can
  // successfully pass.
  tolerance_ = 4.0*Eigen::NumTraits<double>::epsilon();

  int nq = tree_.number_of_positions();
  int nv = tree_.number_of_velocities();
  int num_states = nq + nv;
  VectorXd x = VectorXd::Zero(num_states);
  x.head(nq) = tree_.getZeroConfiguration();

  auto q = x.topRows(nq);
  auto v = x.bottomRows(nv);

  KinematicsCache<double> kinsol = tree_.doKinematics(q, v);

  std::vector<DrakeCollision::PointPair> collision_pairs =
      tree_.ComputeMaximumDepthCollisionPoints(
      kinsol, false);

  // RigidBodyTree::ComputeMaximumDepthCollisionPoints returns only one point,
  // the maximum depth collision point.
  ASSERT_EQ(1, collision_pairs.size());

  const RigidBody* bodyA = collision_pairs[0].elementA->get_body();
  const RigidBody* bodyB = collision_pairs[0].elementB->get_body();

  EXPECT_NEAR(-0.1, collision_pairs[0].distance, tolerance_);
  EXPECT_TRUE(collision_pairs[0].normal.isApprox(Vector3d(0.0, -1.0, 0.0)));

  // Collision points are reported on each of the respective bodies' frames.
  EXPECT_TRUE(collision_pairs[0].ptA.isApprox(
      solution_[bodyA].body_frame, tolerance_));

  // In body's frame, which is rotated 90 degrees in pitch from
  // collision_test.sdf, the collision point is on the z-axis.
  // In addition, is not at z=0.5 but at z=0.6 since there is an offset of 0.1
  // in body's z-axis for the collision element as set from collision_test.sdf.
  EXPECT_TRUE(collision_pairs[0].ptB.isApprox(
      solution_[bodyB].body_frame, tolerance_));
}

}  // namespace
}  // namespace rigid_body_tree
}  // namespace test
}  // namespace plants
}  // namespace systems
}  // namespace drake
<commit_msg>Adds EIGEN_MAKE_ALIGNED_OPERATOR_NEW to test fixture.<commit_after>#include <memory>

#include "drake/Path.h"
#include "drake/systems/plants/RigidBodyTree.h"

#include "gtest/gtest.h"
#include "gmock/gmock.h"

namespace drake {
namespace systems {
namespace plants {
namespace test {
namespace rigid_body_tree {
namespace {

using Eigen::Vector3d;
using Eigen::VectorXd;
using Eigen::Matrix3Xd;

// Structure used to hold the analytical solution of the tests.
// It stores the collision point on the surface of a collision body in both
// world and body frames.
// See systems/plants/collision/test/model_test.cc.
struct SurfacePoint {
  SurfacePoint() { }
  SurfacePoint(Vector3d wf, Vector3d bf) : world_frame(wf), body_frame(bf) { }
  // Eigen variables are left uninitalized by default.
  Vector3d world_frame;
  Vector3d body_frame;
};

// Solutions are accessed by rigid body pointer using an std::unordered_map.
// DrakeCollision::Model returns the collision detection results as a vector of
// DrakeCollision::PointPair entries. Each entry holds a reference to the pair
// of collision elements taking part in the collision.
// To provide a simple access to the appropriate solution for the collision
// point on each body, a map is used to allow referencing the corresponding
// solution by body pointer.
typedef std::unordered_map<const RigidBody*, SurfacePoint>
    BodyToSurfacePointMap;

class RBTCollisionTest: public ::testing::Test {
 protected:
  void SetUp() override {
    tree_.addRobotFromSDF(
        Drake::getDrakePath() +
        "/systems/plants/test/rigid_body_tree/small_sphere_on_large_box.sdf",
        DrakeJoint::QUATERNION);

    small_sphere_ = tree_.FindBody("small_sphere");
    large_box_ = tree_.FindBody("large_box");

    // Access the analytical solution to the contact point on the surface of
    // each collision element by element id.
    // Solutions are expressed in world and body frames.
    solution_ = {
        /*              world frame    , body frame  */
        {large_box_,    {{0.0, 5.0, 0.0}, {0.0, 2.5, 0.0}}},
        {small_sphere_, {{0.0, 4.9, 0.0}, {0.0, 0.0, 0.6}}}};
  }

  double tolerance_;
  RigidBodyTree tree_;
  const RigidBody *small_sphere_, *large_box_;
  BodyToSurfacePointMap solution_;
 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

// This unit test assesses the correct return from
// RigidBodyTree::ComputeMaximumDepthCollisionPoints.
// The test consists on finding the maximum depth penetration point between a
// sphere and a box.
TEST_F(RBTCollisionTest, FindAndComputeContactPoints) {
  // Numerical precision tolerance to perform floating point comparisons.
  // Its magnitude was chosen to be the minimum value for which these tests can
  // successfully pass.
  tolerance_ = 4.0*Eigen::NumTraits<double>::epsilon();

  int nq = tree_.number_of_positions();
  int nv = tree_.number_of_velocities();
  int num_states = nq + nv;
  VectorXd x = VectorXd::Zero(num_states);
  x.head(nq) = tree_.getZeroConfiguration();

  auto q = x.topRows(nq);
  auto v = x.bottomRows(nv);

  KinematicsCache<double> kinsol = tree_.doKinematics(q, v);

  std::vector<DrakeCollision::PointPair> collision_pairs =
      tree_.ComputeMaximumDepthCollisionPoints(
      kinsol, false);

  // RigidBodyTree::ComputeMaximumDepthCollisionPoints returns only one point,
  // the maximum depth collision point.
  ASSERT_EQ(1, collision_pairs.size());

  const RigidBody* bodyA = collision_pairs[0].elementA->get_body();
  const RigidBody* bodyB = collision_pairs[0].elementB->get_body();

  EXPECT_NEAR(-0.1, collision_pairs[0].distance, tolerance_);
  EXPECT_TRUE(collision_pairs[0].normal.isApprox(Vector3d(0.0, -1.0, 0.0)));

  // Collision points are reported on each of the respective bodies' frames.
  EXPECT_TRUE(collision_pairs[0].ptA.isApprox(
      solution_[bodyA].body_frame, tolerance_));

  // In body's frame, which is rotated 90 degrees in pitch from
  // collision_test.sdf, the collision point is on the z-axis.
  // In addition, is not at z=0.5 but at z=0.6 since there is an offset of 0.1
  // in body's z-axis for the collision element as set from collision_test.sdf.
  EXPECT_TRUE(collision_pairs[0].ptB.isApprox(
      solution_[bodyB].body_frame, tolerance_));
}

}  // namespace
}  // namespace rigid_body_tree
}  // namespace test
}  // namespace plants
}  // namespace systems
}  // namespace drake
<|endoftext|>


<commit_before>#include "Graph.h"
#include <fstream>
#include <string>
using namespace std;

int main(int argc, char **argv)
{
    string filename = "graph.txt";
    if (argc > 1){
        filename = argv[1];
        cout <<"reading file : " << filename << endl;
    }
    std::ifstream infile(filename);
    int linecounter = 0;
    int a, b;
    Graph g;

	while (infile >> a >> b)
	{
        if (linecounter == 0){
            g.init(a);
        }else{
            g.addEdge(a, b);
        }
		cout << a << "," << b<< endl;
        linecounter++;
	}
    /*
    // Create a graph given in the above diagram
    Graph g(4);
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(1, 2);
    g.addEdge(2, 0);
    g.addEdge(2, 3);
    g.addEdge(3, 3);
    */
    cout << "Following is Depth First Traversal (starting from vertex 2) \n";
    g.DFS(2);
    cout << endl ;

    cout << "Following is Breadth First Traversal "
                 << "(starting from vertex 2) \n";
    g.BFS(2);
    cout << endl ;
    return 0;
}
<commit_msg>update indent<commit_after>#include "Graph.h"
#include <fstream>
#include <string>
using namespace std;

int main(int argc, char **argv)
{
    string filename = "graph.txt";
    if (argc > 1){
        filename = argv[1];
        cout <<"reading file : " << filename << endl;
    }
    std::ifstream infile(filename);
    int linecounter = 0;
    int a, b;
    Graph g;
    while (infile >> a >> b)
    {
        if (linecounter == 0){
            g.init(a);
        }else{
            g.addEdge(a, b);
        }
        cout << a << "," << b<< endl;
        linecounter++;
    }
    /*
    // Create a graph given in the above diagram
    Graph g(4);
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(1, 2);
    g.addEdge(2, 0);
    g.addEdge(2, 3);
    g.addEdge(3, 3);
    */
    cout << "Following is Depth First Traversal (starting from vertex 2) \n";
    g.DFS(2);
    cout << endl ;

    cout << "Following is Breadth First Traversal "
                 << "(starting from vertex 2) \n";
    g.BFS(2);
    cout << endl ;
    return 0;
}
<|endoftext|>


<commit_before>
#include "pagedblob.h"

namespace glib {

	/// Assignment operator
	TPgBlobPt& TPgBlobPt::operator = (const TPgBlobPt& Pt) {
		if (this != &Pt) {
			Page = Pt.Page;
			FileIndex = Pt.FileIndex;
			ItemIndex = Pt.ItemIndex;
		}
		return *this;
	}

	/// Equality comparer
	bool TPgBlobPt::operator==(const TPgBlobPt& Pt) const {
		return
			(Page == Pt.Page) &&
			(FileIndex == Pt.FileIndex) &&
			(ItemIndex == Pt.ItemIndex);
	}

	/// Comparison of pointers for sorting
	bool TPgBlobPt::operator<(const TPgBlobPt& Pt) const {
		return
			(FileIndex < Pt.FileIndex) ||
			((FileIndex == Pt.FileIndex) && (Page < Pt.Page)) ||
			((FileIndex == Pt.FileIndex) && (Page == Pt.Page) && (ItemIndex < Pt.ItemIndex));
	}

	/////////////////////////////////////////////////////////////////////////////

	/// Private constructor
	TPgBlobFile::TPgBlobFile(
		const TStr& _FNm, const TFAccess& _Access, const uint32& _MxSegLen) {

		Access = _Access;
		FNm = _FNm;
		MxFileLen = _MxSegLen*PAGE_SIZE;

		switch (Access) {
		case faCreate:
			FileId = fopen(FNm.CStr(), "w+b");
			break;
		case faRdOnly:
			FileId = fopen(FNm.CStr(), "rb");
			break;
		case faAppend:
			FileId = fopen(FNm.CStr(), "r+b");
			if (FileId != NULL) {
				fseek(FileId, SEEK_END, 0);
			}
			break;
		case faUpdate:
			FileId = fopen(FNm.CStr(), "r+b");
			break;
		default:
			break;
		}
	}

	/// Destructor
	TPgBlobFile::~TPgBlobFile() {
		EAssertR(
			fclose(FileId) == 0,
			"Can not close file '" + TStr(FNm.CStr()) + "'.");
	}

	/// Load page with given index from the file into buffer
	int TPgBlobFile::LoadPage(const uint32& Page, void* Bf) {
		SetFPos(Page * PAGE_SIZE);
		EAssertR(
			fread(Bf, 1, PAGE_SIZE, FileId) == PAGE_SIZE,
			"Error reading file '" + TStr(FNm) + "'.");
		return 0;
	}

	/// Save buffer to page within the file
	int TPgBlobFile::SavePage(const uint32& Page, const void* Bf) {
		SetFPos(Page * PAGE_SIZE);
		EAssertR(
			fwrite(Bf, 1, PAGE_SIZE, FileId) == PAGE_SIZE,
			"Error reading file '" + TStr(FNm) + "'.");
		return 0;
	}

	/// Refresh the position - internal check
	void TPgBlobFile::RefreshFPos() {
		EAssertR(
			fseek(FileId, 0, SEEK_CUR) == 0,
			"Error seeking into file '" + TStr(FNm) + "'.");
	}

	/// Set position in the file
	void TPgBlobFile::SetFPos(const int& FPos) {
		EAssertR(
			fseek(FileId, FPos, SEEK_SET) == 0,
			"Error seeking into file '" + TStr(FNm) + "'.");
	}

	/// Save buffer to page within the file
	uint32 TPgBlobFile::CreateNewPage() {
		EAssertR(
			fseek(FileId, 0, SEEK_END) == 0,
			"Error seeking into file '" + TStr(FNm) + "'.");
		long len = ftell(FileId);
		if (MxFileLen > 0 && len >= MxFileLen) {
			return -1;
		}
		return (uint32)(len / PAGE_SIZE);
	}

	///////////////////////////////////////////////////////////////////////////

	TPgBlobPage::TPgBlobPage() {}

	TPgBlobPage::~TPgBlobPage() {}

	///////////////////////////////////////////////////////////////////////////

	/// Private constructor
	TPgBlob::TPgBlob(const TStr& _FNm, const TFAccess& _Access, const uint64& CacheSize) {

		EAssertR(
			CacheSize >= PAGE_SIZE,
			"Invalid cache size for TPgBlob.");

		FNm = _FNm;
		Access = _Access;
		switch (Access) {
		case faCreate:
			TFile::DelWc(FNm + ".*");
			SaveMain();
			break;
		case faRdOnly:
		case faUpdate:
			LoadMain();
			break;
		default:
			FailR("Unsupported TFAccess flag for TPgBlob.");
		}

		// init cache
		Bf = new byte[CacheSize];
		BfL = CacheSize;
		MxLoadedPages = CacheSize / PAGE_SIZE;
		LruFirst = LruLast = -1;
	}

	/// Destructor
	TPgBlob::~TPgBlob() {
		for (int i = 0; i < LoadedPages.Len(); i++) {
			if (ShouldSavePage(i)) {
				LoadedPage& a = LoadedPages[i];
				Files[a.Pt.GetFileIndex()]->SavePage(a.Pt.GetPage(), GetPageBf(i));
			}
		}
		Files.Clr();
		delete[] Bf;
	}

	/// Save main file
	void TPgBlob::SaveMain() {
		PSOut SOut = TFOut::New(FNm + ".main");
		TInt children_cnt(Files.Len());
		SOut->Save(children_cnt);
	}
	/// Load main file
	void TPgBlob::LoadMain() {
		PSIn SIn = TFIn::New(FNm + ".main");
		int children_cnt;
		SIn->Load(children_cnt);
		Files.Clr();
		for (int i = 0; i < children_cnt; i++) {
			TStr FNmChild = FNm + ".bin" + TStr::GetNrNumFExt(children_cnt);
			Files.Add(TPgBlobFile::New(FNmChild, Access, TInt::Giga));
		}
	}

	/// Factory method for creating new BLOB storage
	PPgBlob TPgBlob::Create(const TStr& FNm, const uint64& CacheSize) {
		return PPgBlob(new TPgBlob(FNm, TFAccess::faCreate, CacheSize));
	}

	/// Factory method for opening existing BLOB storage
	PPgBlob TPgBlob::Open(const TStr& FNm, const uint64& CacheSize) {
		return PPgBlob(new TPgBlob(FNm, TFAccess::faUpdate, CacheSize));
	}

	/// remove given page from LRU list
	void TPgBlob::UnlistFromLru(int Pg) {
		LoadedPage& a = LoadedPages[Pg];
		if (LruFirst == Pg) {
			LruFirst = a.LruNext;
		}
		if (LruLast == Pg) {
			LruLast = a.LruPrev;
		}
		if (a.LruNext >= 0) {
			LoadedPages[a.LruNext].LruPrev = a.LruPrev;
		}
		if (a.LruPrev >= 0) {
			LoadedPages[a.LruPrev].LruNext = a.LruNext;
		}
	}
	/// insert given (new) page to the start of LRU list
	void TPgBlob::EnlistToStartLru(int Pg) {
		LoadedPage& a = LoadedPages[Pg];
		a.LruPrev = -1;
		a.LruNext = LruFirst;
		if (LruFirst >= 0) {
			LoadedPages[LruFirst].LruPrev = Pg;
		}
		LruFirst = Pg;
	}

	/// move given page to the start of LRU list
	void TPgBlob::MoveToStartLru(int Pg) {
		LoadedPage& a = LoadedPages[Pg];
		if (LruFirst < 0) { // empty LRU list
			a.LruNext = a.LruPrev = -1;
			LruFirst = LruLast = Pg;
		} else {
			UnlistFromLru(Pg);
			EnlistToStartLru(Pg);
		}
	}

	/// Evicts last possible page from cache.
	int TPgBlob::Evict() {
		int Pg = LruLast;
		while (Pg != LruFirst) {
			if (CanEvictPage(Pg)) {
				break;
			}
			Pg = LoadedPages[Pg].LruPrev;
		}
		LoadedPage& a = LoadedPages[Pg];
		UnlistFromLru(Pg);
		LoadedPagesH.DelKey(a.Pt);
		if (ShouldSavePage(Pg)) {
			Files[a.Pt.GetFileIndex()]->SavePage(a.Pt.GetPage(), GetPageBf(Pg));
		}
		return Pg;
	}
	/// Load given page into memory
	byte* TPgBlob::LoadPage(const TPgBlobPt& Pt) {
		int Pg;
		if (LoadedPagesH.IsKeyGetDat(Pt, Pg)) { // is page in cache
			MoveToStartLru(Pg);
			return GetPageBf(Pg);
		}
		if (LoadedPages.Len() == MxLoadedPages) {
			// evict last page + load new page
			Pg = Evict();
			LoadedPage& a = LoadedPages[Pg];
			Files[Pt.GetFileIndex()]->LoadPage(Pt.GetPage(), GetPageBf(Pg));
			a.Pt = Pt;
			EnlistToStartLru(Pg);
			int hid = LoadedPagesH.AddKey(Pt);
			LoadedPagesH(Pt) = Pg;
		} else {
			// simply load the page
			Pg = LoadedPages.Add();
			LoadedPage& a = LoadedPages[Pg];
			Files[Pt.GetFileIndex()]->LoadPage(Pt.GetPage(), GetPageBf(Pg));
			a.Pt = Pt;
			EnlistToStartLru(Pg);
			int hid = LoadedPagesH.AddKey(Pt);
			LoadedPagesH[hid] = Pg;
		}
		return GetPageBf(Pg);
	}

	/// Create new page and return pointers to it
	TPair<TPgBlobPt, byte*> TPgBlob::CreateNewPage() {
		TPair<TPgBlobPt, byte*> res;
		// determine if last file is empty
		if (Files.Len() > 0) {
			// try to add to last file
			uint32 Pg = Files.Last()->CreateNewPage();
			if (Pg >= 0) {
				res.Val1 = TPgBlobPt(Pg, Files.Len() - 1, 0);
				res.Val2 = LoadPage(res.Val1);
				return res;
			}
		}
		TStr NewFNm = FNm + ".bin" + TStr::GetNrNumFExt(Files.Len());
		Files.Add(TPgBlobFile::New(NewFNm, TFAccess::faCreate, TInt::Giga));
		uint32 Pg = Files.Last()->CreateNewPage();
		EAssert(Pg >= 0);
		res.Val1 = TPgBlobPt(Pg, Files.Len() - 1, 0);
		res.Val2 = LoadPage(res.Val1);
		return res;
	}
}<commit_msg>fixed whitespaces<commit_after>
#include "pagedblob.h"

namespace glib {

	/// Assignment operator
	TPgBlobPt& TPgBlobPt::operator = (const TPgBlobPt& Pt) {
		if (this != &Pt) {
			Page = Pt.Page;
			FileIndex = Pt.FileIndex;
			ItemIndex = Pt.ItemIndex;
		}
		return *this;
	}

	/// Equality comparer
	bool TPgBlobPt::operator==(const TPgBlobPt& Pt) const {
		return
			(Page == Pt.Page) &&
			(FileIndex == Pt.FileIndex) &&
			(ItemIndex == Pt.ItemIndex);
	}

	/// Comparison of pointers for sorting
	bool TPgBlobPt::operator<(const TPgBlobPt& Pt) const {
		return
			(FileIndex < Pt.FileIndex) ||
			((FileIndex == Pt.FileIndex) && (Page < Pt.Page)) ||
			((FileIndex == Pt.FileIndex) && (Page == Pt.Page) && (ItemIndex < Pt.ItemIndex));
	}

	/////////////////////////////////////////////////////////////////////////////

	/// Private constructor
	TPgBlobFile::TPgBlobFile(
		const TStr& _FNm, const TFAccess& _Access, const uint32& _MxSegLen) {

		Access = _Access;
		FNm = _FNm;
		MxFileLen = _MxSegLen*PAGE_SIZE;

		switch (Access) {
		case faCreate:
			FileId = fopen(FNm.CStr(), "w+b");
			break;
		case faRdOnly:
			FileId = fopen(FNm.CStr(), "rb");
			break;
		case faAppend:
			FileId = fopen(FNm.CStr(), "r+b");
			if (FileId != NULL) {
				fseek(FileId, SEEK_END, 0);
			}
			break;
		case faUpdate:
			FileId = fopen(FNm.CStr(), "r+b");
			break;
		default:
			break;
		}
	}

	/// Destructor
	TPgBlobFile::~TPgBlobFile() {
		EAssertR(
			fclose(FileId) == 0,
			"Can not close file '" + TStr(FNm.CStr()) + "'.");
	}

	/// Load page with given index from the file into buffer
	int TPgBlobFile::LoadPage(const uint32& Page, void* Bf) {
		SetFPos(Page * PAGE_SIZE);
		EAssertR(
			fread(Bf, 1, PAGE_SIZE, FileId) == PAGE_SIZE,
			"Error reading file '" + TStr(FNm) + "'.");
		return 0;
	}

	/// Save buffer to page within the file
	int TPgBlobFile::SavePage(const uint32& Page, const void* Bf) {
		SetFPos(Page * PAGE_SIZE);
		EAssertR(
			fwrite(Bf, 1, PAGE_SIZE, FileId) == PAGE_SIZE,
			"Error reading file '" + TStr(FNm) + "'.");
		return 0;
	}

	/// Refresh the position - internal check
	void TPgBlobFile::RefreshFPos() {
		EAssertR(
			fseek(FileId, 0, SEEK_CUR) == 0,
			"Error seeking into file '" + TStr(FNm) + "'.");
	}

	/// Set position in the file
	void TPgBlobFile::SetFPos(const int& FPos) {
		EAssertR(
			fseek(FileId, FPos, SEEK_SET) == 0,
			"Error seeking into file '" + TStr(FNm) + "'.");
	}

	/// Save buffer to page within the file
	uint32 TPgBlobFile::CreateNewPage() {
		EAssertR(
			fseek(FileId, 0, SEEK_END) == 0,
			"Error seeking into file '" + TStr(FNm) + "'.");
		long len = ftell(FileId);
		if (MxFileLen > 0 && len >= MxFileLen) {
			return -1;
		}
		return (uint32)(len / PAGE_SIZE);
	}

	///////////////////////////////////////////////////////////////////////////

	TPgBlobPage::TPgBlobPage() {}

	TPgBlobPage::~TPgBlobPage() {}

	///////////////////////////////////////////////////////////////////////////

	/// Private constructor
	TPgBlob::TPgBlob(const TStr& _FNm, const TFAccess& _Access, const uint64& CacheSize) {

		EAssertR( CacheSize >= PAGE_SIZE, "Invalid cache size for TPgBlob.");

		FNm = _FNm;
		Access = _Access;

		switch (Access) {
		case faCreate:
			TFile::DelWc(FNm + ".*");
			SaveMain();
			break;
		case faRdOnly:
		case faUpdate:
			LoadMain();
			break;
		default:
			FailR("Unsupported TFAccess flag for TPgBlob.");
		}

		// init cache
		Bf = new byte[CacheSize];
		BfL = CacheSize;
		MxLoadedPages = CacheSize / PAGE_SIZE;
		LruFirst = LruLast = -1;
	}

	/// Destructor
	TPgBlob::~TPgBlob() {
		for (int i = 0; i < LoadedPages.Len(); i++) {
			if (ShouldSavePage(i)) {
				LoadedPage& a = LoadedPages[i];
				Files[a.Pt.GetFileIndex()]->SavePage(a.Pt.GetPage(), GetPageBf(i));
			}
		}
		Files.Clr();
		delete[] Bf;
	}

	/// Save main file
	void TPgBlob::SaveMain() {
		PSOut SOut = TFOut::New(FNm + ".main");
		TInt children_cnt(Files.Len());
		SOut->Save(children_cnt);
	}

	/// Load main file
	void TPgBlob::LoadMain() {
		PSIn SIn = TFIn::New(FNm + ".main");
		int children_cnt;
		SIn->Load(children_cnt);
		Files.Clr();
		for (int i = 0; i < children_cnt; i++) {
			TStr FNmChild = FNm + ".bin" + TStr::GetNrNumFExt(children_cnt);
			Files.Add(TPgBlobFile::New(FNmChild, Access, TInt::Giga));
		}
	}

	/// Factory method for creating new BLOB storage
	PPgBlob TPgBlob::Create(const TStr& FNm, const uint64& CacheSize) {
		return PPgBlob(new TPgBlob(FNm, TFAccess::faCreate, CacheSize));
	}

	/// Factory method for opening existing BLOB storage
	PPgBlob TPgBlob::Open(const TStr& FNm, const uint64& CacheSize) {
		return PPgBlob(new TPgBlob(FNm, TFAccess::faUpdate, CacheSize));
	}

	/// remove given page from LRU list
	void TPgBlob::UnlistFromLru(int Pg) {
		LoadedPage& a = LoadedPages[Pg];
		if (LruFirst == Pg) {
			LruFirst = a.LruNext;
		}
		if (LruLast == Pg) {
			LruLast = a.LruPrev;
		}
		if (a.LruNext >= 0) {
			LoadedPages[a.LruNext].LruPrev = a.LruPrev;
		}
		if (a.LruPrev >= 0) {
			LoadedPages[a.LruPrev].LruNext = a.LruNext;
		}
	}

	/// insert given (new) page to the start of LRU list
	void TPgBlob::EnlistToStartLru(int Pg) {
		LoadedPage& a = LoadedPages[Pg];
		a.LruPrev = -1;
		a.LruNext = LruFirst;
		if (LruFirst >= 0) {
			LoadedPages[LruFirst].LruPrev = Pg;
		}
		LruFirst = Pg;
	}

	/// move given page to the start of LRU list
	void TPgBlob::MoveToStartLru(int Pg) {
		LoadedPage& a = LoadedPages[Pg];
		if (LruFirst < 0) { // empty LRU list
			a.LruNext = a.LruPrev = -1;
			LruFirst = LruLast = Pg;
		} else {
			UnlistFromLru(Pg);
			EnlistToStartLru(Pg);
		}
	}

	/// Evicts last possible page from cache.
	int TPgBlob::Evict() {
		int Pg = LruLast;
		while (Pg != LruFirst) {
			if (CanEvictPage(Pg)) {
				break;
			}
			Pg = LoadedPages[Pg].LruPrev;
		}
		LoadedPage& a = LoadedPages[Pg];
		UnlistFromLru(Pg);
		LoadedPagesH.DelKey(a.Pt);
		if (ShouldSavePage(Pg)) {
			Files[a.Pt.GetFileIndex()]->SavePage(a.Pt.GetPage(), GetPageBf(Pg));
		}
		return Pg;
	}

	/// Load given page into memory
	byte* TPgBlob::LoadPage(const TPgBlobPt& Pt) {
		int Pg;
		if (LoadedPagesH.IsKeyGetDat(Pt, Pg)) { // is page in cache
			MoveToStartLru(Pg);
			return GetPageBf(Pg);
		}
		if (LoadedPages.Len() == MxLoadedPages) {
			// evict last page + load new page
			Pg = Evict();
			LoadedPage& a = LoadedPages[Pg];
			Files[Pt.GetFileIndex()]->LoadPage(Pt.GetPage(), GetPageBf(Pg));
			a.Pt = Pt;
			EnlistToStartLru(Pg);
			int hid = LoadedPagesH.AddKey(Pt);
			LoadedPagesH(Pt) = Pg;
		} else {
			// simply load the page
			Pg = LoadedPages.Add();
			LoadedPage& a = LoadedPages[Pg];
			Files[Pt.GetFileIndex()]->LoadPage(Pt.GetPage(), GetPageBf(Pg));
			a.Pt = Pt;
			EnlistToStartLru(Pg);
			int hid = LoadedPagesH.AddKey(Pt);
			LoadedPagesH[hid] = Pg;
		}
		return GetPageBf(Pg);
	}

	/// Create new page and return pointers to it
	TPair<TPgBlobPt, byte*> TPgBlob::CreateNewPage() {
		TPair<TPgBlobPt, byte*> res;
		// determine if last file is empty
		if (Files.Len() > 0) {
			// try to add to last file
			uint32 Pg = Files.Last()->CreateNewPage();
			if (Pg >= 0) {
				res.Val1 = TPgBlobPt(Pg, Files.Len() - 1, 0);
				res.Val2 = LoadPage(res.Val1);
				return res;
			}
		}
		TStr NewFNm = FNm + ".bin" + TStr::GetNrNumFExt(Files.Len());
		Files.Add(TPgBlobFile::New(NewFNm, TFAccess::faCreate, TInt::Giga));
		uint32 Pg = Files.Last()->CreateNewPage();
		EAssert(Pg >= 0);
		res.Val1 = TPgBlobPt(Pg, Files.Len() - 1, 0);
		res.Val2 = LoadPage(res.Val1);
		return res;
	}
}<|endoftext|>


<commit_before>#include "ContextCairo.h"

#include <cassert>
#include <cmath>
#include <iostream>

using namespace canvas;
using namespace std;

CairoSurface::CairoSurface(unsigned int _logical_width, unsigned int _logical_height, unsigned int _actual_width, unsigned int _actual_height, bool has_alpha)
  : Surface(_logical_width, _logical_height, _actual_width, _actual_height) {
  cairo_format_t format = has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
  surface = cairo_image_surface_create(format, _actual_width, _actual_height);
  assert(surface);
}

CairoSurface::CairoSurface(const Image & image)
  : Surface(image.getWidth(), image.getHeight(), image.getWidth(), image.getHeight())
{
  cairo_format_t format = image.hasAlpha() ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
  unsigned int stride = cairo_format_stride_for_width(format, getActualWidth());
  assert(stride == 4 * getActualWidth());
  storage = new unsigned int[getActualWidth() * getActualHeight()];
  const unsigned char * data = image.getData();
  if (image.hasAlpha()) {
    for (unsigned int i = 0; i < getActualWidth() * getActualHeight(); i++) {
#if 0
      storage[i] = (data[4 * i + 0] << 24) + (data[4 * i + 1] << 16) + (data[4 * i + 2] << 8) + data[4 * i + 3];
#else
      storage[i] = (data[4 * i + 0]) + (data[4 * i + 1] << 8) + (data[4 * i + 2] << 16) + (data[4 * i + 3] << 24);
#endif
    }
  } else {
    for (unsigned int i = 0; i < getActualWidth() * getActualHeight(); i++) {
      storage[i] = data[3 * i + 2] + (data[3 * i + 1] << 8) + (data[3 * i + 0] << 16);
    }
  }
  surface = cairo_image_surface_create_for_data((unsigned char*)storage,
						format,
						getActualWidth(),
						getActualHeight(),
						stride);
  assert(surface);
}

CairoSurface::CairoSurface(const std::string & filename) : Surface(0, 0, 0, 0) {
  surface = cairo_image_surface_create_from_png(filename.c_str());
  assert(surface);
  unsigned int w = cairo_image_surface_get_width(surface), h = cairo_image_surface_get_height(surface);
  Surface::resize(w, h, w, h);
}

struct read_buffer_s {
  size_t offset, size;
  const unsigned char * data;
};

static cairo_status_t read_buffer(void *closure, unsigned char *data, unsigned int length)
{
  read_buffer_s * buf = (read_buffer_s*)closure;

  if (buf->offset + length > buf->size) {
    return CAIRO_STATUS_READ_ERROR;
  }
  memcpy(data, buf->data + buf->offset, length);
  buf->offset += length;
  return CAIRO_STATUS_SUCCESS;
}

CairoSurface::CairoSurface(const unsigned char * buffer, size_t size) : Surface(16, 16, 16, 16) {
  read_buffer_s buf = { 0, size, buffer };
  if (isPNG(buffer, size)) {
    surface = cairo_image_surface_create_from_png_stream(read_buffer, &buf);
    unsigned int w = cairo_image_surface_get_width(surface), h = cairo_image_surface_get_height(surface);
    Surface::resize(w, h, w, h);
  } else {
    cerr << "failed to load image from memory\n";
    surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, getActualWidth(), getActualHeight());
  }
  assert(surface);
}

CairoSurface::~CairoSurface() {
  if (cr) {
    cairo_destroy(cr);
  }
  if (surface) {
    cairo_surface_destroy(surface);
  }
  delete[] storage;
}

void
CairoSurface::flush() {
  cairo_surface_flush(surface);
}

void
CairoSurface::markDirty() {
  cairo_surface_mark_dirty(surface);
}

void
CairoSurface::resize(unsigned int _logical_width, unsigned int _logical_height, unsigned int _actual_width, unsigned int _actual_height) {
  Surface::resize(_logical_width, _logical_height, _actual_width, _actual_height);
  if (cr) {
    cairo_destroy(cr);
    cr = 0;
  }
  if (surface) cairo_surface_destroy(surface);
  cairo_format_t format = CAIRO_FORMAT_ARGB32;
  // format = CAIRO_FORMAT_RGB24;
  surface = cairo_image_surface_create(format, _actual_width, _actual_height);
  assert(surface);
}

void
CairoSurface::sendPath(const Path & path) {
  initializeContext();
  for (auto pc : path.getData()) {
    switch (pc.type) {
    case PathComponent::MOVE_TO: cairo_move_to(cr, pc.x0 + 0.5, pc.y0 + 0.5); break;
    case PathComponent::LINE_TO: cairo_line_to(cr, pc.x0 + 0.5, pc.y0 + 0.5); break;
    case PathComponent::CLOSE: cairo_close_path(cr); break;
    case PathComponent::ARC:
      if (!pc.anticlockwise) {
	cairo_arc(cr, pc.x0 + 0.5, pc.y0 + 0.5, pc.radius, pc.sa, pc.ea);
      } else {
	cairo_arc_negative(cr, pc.x0 + 0.5, pc.y0 + 0.5, pc.radius, pc.sa, pc.ea);
      }
      break;
    }
  }
}

void
CairoSurface::clip(const Path & path, float display_scale) {
  sendPath(path);
  cairo_clip(cr);
}

void
CairoSurface::renderPath(RenderMode mode, const Path & path, const Style & style, float lineWidth, float display_scale) {
  initializeContext();
  cairo_pattern_t * pat = 0;
  if (style.getType() == Style::LINEAR_GRADIENT) {
    pat = cairo_pattern_create_linear(style.x0 * display_scale, style.y0 * display_scale, style.x1 * display_scale, style.y1 * display_scale);
    for (map<float, Color>::const_iterator it = style.getColors().begin(); it != style.getColors().end(); it++) {
      cairo_pattern_add_color_stop_rgba(pat, it->first, it->second.red, it->second.green, it->second.blue, it->second.alpha);
    }
    cairo_set_source(cr, pat);
  } else if (style.getType() == Style::FILTER) {
    double min_x, min_y, max_x, max_y;
    path.getExtents(min_x, min_y, max_x, max_y);
  } else {
    cairo_set_source_rgba(cr, style.color.red, style.color.green, style.color.blue, style.color.alpha);
  }
  sendPath(path);
  switch (mode) {
  case STROKE:
    cairo_set_line_width(cr, lineWidth);
    // cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
    cairo_stroke(cr);
    break;
  case FILL:
    cairo_fill(cr);
    break;
  }

  if (pat) {
    cairo_pattern_destroy(pat);
    cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  }
}

void
CairoSurface::renderText(RenderMode mode, const Font & font, const Style & style, TextBaseline textBaseline, TextAlign textAlign, const std::string & text, double x, double y, float lineWidth, float display_scale) {
  initializeContext();
  cairo_set_source_rgba(cr, style.color.red, style.color.green, style.color.blue, style.color.alpha);
  cairo_select_font_face(cr, font.family.c_str(),
			 font.slant == Font::NORMAL_SLANT ? CAIRO_FONT_SLANT_NORMAL : (font.slant == Font::ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_OBLIQUE),
			 font.weight == Font::NORMAL || font.weight == Font::LIGHTER ? CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(cr, font.size * display_scale);

  x *= display_scale;
  y *= display_scale;

  if (textBaseline.getType() == TextBaseline::MIDDLE || textBaseline.getType() == TextBaseline::TOP) {
    cairo_font_extents_t font_extents;
    cairo_font_extents(cr, &font_extents);

    switch (textBaseline.getType()) {
      // case TextBaseline::MIDDLE: y -= (extents.height/2 + extents.y_bearing); break;
    case TextBaseline::MIDDLE: y += -font_extents.descent + (font_extents.ascent + font_extents.descent) / 2.0; break;
    case TextBaseline::TOP: y += font_extents.ascent; break;
    default: break;
    }
  }

  if (textAlign.getType() != TextAlign::LEFT) {
    cairo_text_extents_t text_extents;
    cairo_text_extents(cr, text.c_str(), &text_extents);

    switch (textAlign.getType()) {
    case TextAlign::LEFT: break;
    case TextAlign::CENTER: x -= text_extents.width / 2; break;
    case TextAlign::RIGHT: x -= text_extents.width; break;
    default: break;
    }
  }

  cairo_move_to(cr, x + 0.5, y + 0.5);

  switch (mode) {
  case STROKE:
    cairo_set_line_width(cr, lineWidth);
    cairo_text_path(cr, text.c_str());
    cairo_stroke(cr);
    break;
  case FILL:
    cairo_show_text(cr, text.c_str());
    break;
  }
}

// renderText(RenderMode mode, const Font & font, const Style & style, TextBaseline textBaseline, TextAlign textAlign, const std::string & text, double x, double y, float lineWidth, float display_scale) {

TextMetrics
CairoSurface::measureText(const Font & font, const std::string & text, float display_scale) {
  initializeContext();
  cairo_select_font_face(cr, font.family.c_str(),
			 font.slant == Font::NORMAL_SLANT ? CAIRO_FONT_SLANT_NORMAL : (font.slant == Font::ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_OBLIQUE),
			 font.weight == Font::NORMAL || font.weight == Font::LIGHTER ? CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(cr, font.size * display_scale);
  cairo_text_extents_t te;
  cairo_text_extents(cr, text.c_str(), &te);
  return TextMetrics((float)te.width / display_scale); //, (float)te.height);
}

void
CairoSurface::drawNativeSurface(CairoSurface & img, double x, double y, double w, double h, float alpha, bool imageSmoothingEnabled) {
  initializeContext();
  double sx = w / img.getActualWidth(), sy = h / img.getActualHeight();
  cairo_save(cr);
  cairo_scale(cr, sx, sy);
  cairo_set_source_surface(cr, img.surface, (x / sx) + 0.5, (y / sy) + 0.5);
  cairo_pattern_set_filter(cairo_get_source(cr), imageSmoothingEnabled ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_NEAREST);
  if (alpha < 1.0f) {
    cairo_paint_with_alpha(cr, alpha);
  } else {
    cairo_paint(cr);
  }
  cairo_set_source_rgb(cr, 0.0f, 0.0f, 0.0f); // is this needed?
  cairo_restore(cr);
}

void
CairoSurface::drawImage(Surface & _img, double x, double y, double w, double h, float alpha, bool imageSmoothingEnabled) {
  CairoSurface * cs = dynamic_cast<CairoSurface*>(&_img);
  if (cs) {
    drawNativeSurface(*cs, x, y, w, h, alpha, imageSmoothingEnabled);
  } else {
    auto img = _img.createImage();
    CairoSurface cs(*img);
    drawNativeSurface(cs, x, y, w, h, alpha, imageSmoothingEnabled);
  }
}

void
CairoSurface::drawImage(const Image & _img, double x, double y, double w, double h, float alpha, bool imageSmoothingEnabled) {
  CairoSurface img(_img);
  drawNativeSurface(img, x, y, w, h, alpha, imageSmoothingEnabled);
}

void
CairoSurface::save() {
  initializeContext();
  cairo_save(cr);
}

void
CairoSurface::restore() {
  initializeContext();
  cairo_restore(cr);
}
<commit_msg>add has_alpha field<commit_after>#include "ContextCairo.h"

#include <cassert>
#include <cmath>
#include <iostream>

using namespace canvas;
using namespace std;

CairoSurface::CairoSurface(unsigned int _logical_width, unsigned int _logical_height, unsigned int _actual_width, unsigned int _actual_height, bool _has_alpha)
  : Surface(_logical_width, _logical_height, _actual_width, _actual_height, _has_alpha) {
  cairo_format_t format = _has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
  surface = cairo_image_surface_create(format, _actual_width, _actual_height);
  assert(surface);
}

CairoSurface::CairoSurface(const Image & image)
  : Surface(image.getWidth(), image.getHeight(), image.getWidth(), image.getHeight(), image.hasAlpha())
{
  cairo_format_t format = image.hasAlpha() ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
  unsigned int stride = cairo_format_stride_for_width(format, getActualWidth());
  assert(stride == 4 * getActualWidth());
  storage = new unsigned int[getActualWidth() * getActualHeight()];
  const unsigned char * data = image.getData();
  if (image.hasAlpha()) {
    for (unsigned int i = 0; i < getActualWidth() * getActualHeight(); i++) {
#if 0
      storage[i] = (data[4 * i + 0] << 24) + (data[4 * i + 1] << 16) + (data[4 * i + 2] << 8) + data[4 * i + 3];
#else
      storage[i] = (data[4 * i + 0]) + (data[4 * i + 1] << 8) + (data[4 * i + 2] << 16) + (data[4 * i + 3] << 24);
#endif
    }
  } else {
    for (unsigned int i = 0; i < getActualWidth() * getActualHeight(); i++) {
      storage[i] = data[3 * i + 2] + (data[3 * i + 1] << 8) + (data[3 * i + 0] << 16);
    }
  }
  surface = cairo_image_surface_create_for_data((unsigned char*)storage,
						format,
						getActualWidth(),
						getActualHeight(),
						stride);
  assert(surface);
}

CairoSurface::CairoSurface(const std::string & filename) : Surface(0, 0, 0, 0, true) {
  surface = cairo_image_surface_create_from_png(filename.c_str());
  assert(surface);
  unsigned int w = cairo_image_surface_get_width(surface), h = cairo_image_surface_get_height(surface);
  Surface::resize(w, h, w, h);
}

struct read_buffer_s {
  size_t offset, size;
  const unsigned char * data;
};

static cairo_status_t read_buffer(void *closure, unsigned char *data, unsigned int length)
{
  read_buffer_s * buf = (read_buffer_s*)closure;

  if (buf->offset + length > buf->size) {
    return CAIRO_STATUS_READ_ERROR;
  }
  memcpy(data, buf->data + buf->offset, length);
  buf->offset += length;
  return CAIRO_STATUS_SUCCESS;
}

CairoSurface::CairoSurface(const unsigned char * buffer, size_t size) : Surface(16, 16, 16, 16, true) {
  read_buffer_s buf = { 0, size, buffer };
  if (isPNG(buffer, size)) {
    surface = cairo_image_surface_create_from_png_stream(read_buffer, &buf);
    unsigned int w = cairo_image_surface_get_width(surface), h = cairo_image_surface_get_height(surface);
    Surface::resize(w, h, w, h);
  } else {
    cerr << "failed to load image from memory\n";
    surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, getActualWidth(), getActualHeight());
  }
  assert(surface);
}

CairoSurface::~CairoSurface() {
  if (cr) {
    cairo_destroy(cr);
  }
  if (surface) {
    cairo_surface_destroy(surface);
  }
  delete[] storage;
}

void
CairoSurface::flush() {
  cairo_surface_flush(surface);
}

void
CairoSurface::markDirty() {
  cairo_surface_mark_dirty(surface);
}

void
CairoSurface::resize(unsigned int _logical_width, unsigned int _logical_height, unsigned int _actual_width, unsigned int _actual_height) {
  Surface::resize(_logical_width, _logical_height, _actual_width, _actual_height);
  if (cr) {
    cairo_destroy(cr);
    cr = 0;
  }
  if (surface) cairo_surface_destroy(surface);
  cairo_format_t format = CAIRO_FORMAT_ARGB32;
  // format = CAIRO_FORMAT_RGB24;
  surface = cairo_image_surface_create(format, _actual_width, _actual_height);
  assert(surface);
}

void
CairoSurface::sendPath(const Path & path) {
  initializeContext();
  for (auto pc : path.getData()) {
    switch (pc.type) {
    case PathComponent::MOVE_TO: cairo_move_to(cr, pc.x0 + 0.5, pc.y0 + 0.5); break;
    case PathComponent::LINE_TO: cairo_line_to(cr, pc.x0 + 0.5, pc.y0 + 0.5); break;
    case PathComponent::CLOSE: cairo_close_path(cr); break;
    case PathComponent::ARC:
      if (!pc.anticlockwise) {
	cairo_arc(cr, pc.x0 + 0.5, pc.y0 + 0.5, pc.radius, pc.sa, pc.ea);
      } else {
	cairo_arc_negative(cr, pc.x0 + 0.5, pc.y0 + 0.5, pc.radius, pc.sa, pc.ea);
      }
      break;
    }
  }
}

void
CairoSurface::clip(const Path & path, float display_scale) {
  sendPath(path);
  cairo_clip(cr);
}

void
CairoSurface::renderPath(RenderMode mode, const Path & path, const Style & style, float lineWidth, float display_scale) {
  initializeContext();
  cairo_pattern_t * pat = 0;
  if (style.getType() == Style::LINEAR_GRADIENT) {
    pat = cairo_pattern_create_linear(style.x0 * display_scale, style.y0 * display_scale, style.x1 * display_scale, style.y1 * display_scale);
    for (map<float, Color>::const_iterator it = style.getColors().begin(); it != style.getColors().end(); it++) {
      cairo_pattern_add_color_stop_rgba(pat, it->first, it->second.red, it->second.green, it->second.blue, it->second.alpha);
    }
    cairo_set_source(cr, pat);
  } else if (style.getType() == Style::FILTER) {
    double min_x, min_y, max_x, max_y;
    path.getExtents(min_x, min_y, max_x, max_y);
  } else {
    cairo_set_source_rgba(cr, style.color.red, style.color.green, style.color.blue, style.color.alpha);
  }
  sendPath(path);
  switch (mode) {
  case STROKE:
    cairo_set_line_width(cr, lineWidth);
    // cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
    cairo_stroke(cr);
    break;
  case FILL:
    cairo_fill(cr);
    break;
  }

  if (pat) {
    cairo_pattern_destroy(pat);
    cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  }
}

void
CairoSurface::renderText(RenderMode mode, const Font & font, const Style & style, TextBaseline textBaseline, TextAlign textAlign, const std::string & text, double x, double y, float lineWidth, float display_scale) {
  initializeContext();
  cairo_set_source_rgba(cr, style.color.red, style.color.green, style.color.blue, style.color.alpha);
  cairo_select_font_face(cr, font.family.c_str(),
			 font.slant == Font::NORMAL_SLANT ? CAIRO_FONT_SLANT_NORMAL : (font.slant == Font::ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_OBLIQUE),
			 font.weight == Font::NORMAL || font.weight == Font::LIGHTER ? CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(cr, font.size * display_scale);

  x *= display_scale;
  y *= display_scale;

  if (textBaseline.getType() == TextBaseline::MIDDLE || textBaseline.getType() == TextBaseline::TOP) {
    cairo_font_extents_t font_extents;
    cairo_font_extents(cr, &font_extents);

    switch (textBaseline.getType()) {
      // case TextBaseline::MIDDLE: y -= (extents.height/2 + extents.y_bearing); break;
    case TextBaseline::MIDDLE: y += -font_extents.descent + (font_extents.ascent + font_extents.descent) / 2.0; break;
    case TextBaseline::TOP: y += font_extents.ascent; break;
    default: break;
    }
  }

  if (textAlign.getType() != TextAlign::LEFT) {
    cairo_text_extents_t text_extents;
    cairo_text_extents(cr, text.c_str(), &text_extents);

    switch (textAlign.getType()) {
    case TextAlign::LEFT: break;
    case TextAlign::CENTER: x -= text_extents.width / 2; break;
    case TextAlign::RIGHT: x -= text_extents.width; break;
    default: break;
    }
  }

  cairo_move_to(cr, x + 0.5, y + 0.5);

  switch (mode) {
  case STROKE:
    cairo_set_line_width(cr, lineWidth);
    cairo_text_path(cr, text.c_str());
    cairo_stroke(cr);
    break;
  case FILL:
    cairo_show_text(cr, text.c_str());
    break;
  }
}

// renderText(RenderMode mode, const Font & font, const Style & style, TextBaseline textBaseline, TextAlign textAlign, const std::string & text, double x, double y, float lineWidth, float display_scale) {

TextMetrics
CairoSurface::measureText(const Font & font, const std::string & text, float display_scale) {
  initializeContext();
  cairo_select_font_face(cr, font.family.c_str(),
			 font.slant == Font::NORMAL_SLANT ? CAIRO_FONT_SLANT_NORMAL : (font.slant == Font::ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_OBLIQUE),
			 font.weight == Font::NORMAL || font.weight == Font::LIGHTER ? CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(cr, font.size * display_scale);
  cairo_text_extents_t te;
  cairo_text_extents(cr, text.c_str(), &te);
  return TextMetrics((float)te.width / display_scale); //, (float)te.height);
}

void
CairoSurface::drawNativeSurface(CairoSurface & img, double x, double y, double w, double h, float alpha, bool imageSmoothingEnabled) {
  initializeContext();
  double sx = w / img.getActualWidth(), sy = h / img.getActualHeight();
  cairo_save(cr);
  cairo_scale(cr, sx, sy);
  cairo_set_source_surface(cr, img.surface, (x / sx) + 0.5, (y / sy) + 0.5);
  cairo_pattern_set_filter(cairo_get_source(cr), imageSmoothingEnabled ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_NEAREST);
  if (alpha < 1.0f) {
    cairo_paint_with_alpha(cr, alpha);
  } else {
    cairo_paint(cr);
  }
  cairo_set_source_rgb(cr, 0.0f, 0.0f, 0.0f); // is this needed?
  cairo_restore(cr);
}

void
CairoSurface::drawImage(Surface & _img, double x, double y, double w, double h, float alpha, bool imageSmoothingEnabled) {
  CairoSurface * cs = dynamic_cast<CairoSurface*>(&_img);
  if (cs) {
    drawNativeSurface(*cs, x, y, w, h, alpha, imageSmoothingEnabled);
  } else {
    auto img = _img.createImage();
    CairoSurface cs(*img);
    drawNativeSurface(cs, x, y, w, h, alpha, imageSmoothingEnabled);
  }
}

void
CairoSurface::drawImage(const Image & _img, double x, double y, double w, double h, float alpha, bool imageSmoothingEnabled) {
  CairoSurface img(_img);
  drawNativeSurface(img, x, y, w, h, alpha, imageSmoothingEnabled);
}

void
CairoSurface::save() {
  initializeContext();
  cairo_save(cr);
}

void
CairoSurface::restore() {
  initializeContext();
  cairo_restore(cr);
}
<|endoftext|>


<commit_before>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2010 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#ifndef _GRAPHIC
#define _GRAPHIC

#define BGR_LAYER 200
#define APP_LAYER 100
#define NOT_LAYER 0

#include "ofMain.h"

#include "EventClient.hpp"

class Graphic : public EventClient{
    public:
        Graphic();
        Graphic(int _layer);
        Graphic(Graphic & original);
        virtual ~Graphic();
        int GetLayer();
		void BringTop();
		void SafeDelete();
		virtual bool Collide(ofPoint const & point);
		virtual void Position(float & x, float & y);
    protected:
        int layer;
        unsigned long created_time;
        friend class GraphicDispatcher;
        friend class CompareLayers;
        virtual void draw(){}
        virtual void update(){}
        virtual void resize(int w, int h){}
    private:
        bool deleted;
};

template<int Layer>
class TGraphic: public Graphic
{
    public:
    TGraphic():Graphic(Layer){}
};

typedef TGraphic<NOT_LAYER> NotificationGraphic;
typedef TGraphic<BGR_LAYER> BackgroundGraphic;

struct CompareLayers
{
    inline bool operator()(Graphic* object1, Graphic* object2)
    {
        if (object1->GetLayer() == object2->GetLayer())
            return (object1->created_time < object2->created_time);
        return (object1->GetLayer() > object2->GetLayer());
    }
};

//template<typename T>
//class OnTable: public T
//{
//    public:
//    OnTable()
//    {
//        this->Register(NULL);
//    }
//};

#endif //_GRAPHICDISPATCHER
<commit_msg>removing deprecated hook on Graphic<commit_after>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2010 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#ifndef _GRAPHIC
#define _GRAPHIC

#define BGR_LAYER 200
#define APP_LAYER 100
#define NOT_LAYER 0

#include "ofMain.h"

#include "EventClient.hpp"

class Graphic : public EventClient{
    public:
        Graphic();
        Graphic(int _layer);
        Graphic(Graphic & original);
        virtual ~Graphic();
        int GetLayer();
		void BringTop();
		void SafeDelete();
		virtual bool Collide(ofPoint const & point);
		virtual void Position(float & x, float & y); ///DEPRECATED!
    protected:
        int layer;
        unsigned long created_time;
        friend class GraphicDispatcher;
        friend class CompareLayers;
        virtual void draw(){}
        virtual void update(){}
        virtual void resize(int w, int h){}
    private:
        bool deleted;
};

template<int Layer>
class TGraphic: public Graphic
{
    public:
    TGraphic():Graphic(Layer){}
};

typedef TGraphic<NOT_LAYER> NotificationGraphic;
typedef TGraphic<BGR_LAYER> BackgroundGraphic;

struct CompareLayers
{
    inline bool operator()(Graphic* object1, Graphic* object2)
    {
        if (object1->GetLayer() == object2->GetLayer())
            return (object1->created_time < object2->created_time);
        return (object1->GetLayer() > object2->GetLayer());
    }
};

//template<typename T>
//class OnTable: public T
//{
//    public:
//    OnTable()
//    {
//        this->Register(NULL);
//    }
//};

#endif //_GRAPHICDISPATCHER
<|endoftext|>


<commit_before>#ifndef _ATIMER_H
#define _ATIMER_H

#include <vector>
#include <thread>
#include <functional>
#include <boost/timer.hpp>
#include <boost/asio.hpp>

template<typename Duration = boost::posix_time::milliseconds>
class ATimer
{
public:
    ATimer() : m_timer(m_ios, Duration(0)) {}

    void start(unsigned int duration)
    {
        if (m_ios.stopped())
        {
            return;
        }

        m_duration = duration;
        m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
        m_func = [this]
        {
            m_timer.async_wait([this](const boost::system::error_code&)
            {
                for (auto& func : m_funcVec)
                {
                    func();
                }
                m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
                m_func();
            });
        };

        m_func();
        m_thread = std::thread([this]{ m_ios.run(); });
    }

    void stop()
    {
        m_ios.stop();
        if (m_thread.joinable())
        {
            m_thread.join();
        }
    }

    void bind(const std::function<void()>& func)
    {
        m_funcVec.emplace_back(func);
    }

private:
    boost::asio::io_service m_ios;
    boost::asio::deadline_timer m_timer;
    std::function<void()> m_func;
    std::vector<std::function<void()>> m_funcVec;
    std::thread m_thread;
    unsigned int m_duration = 0;
};

#endif
<commit_msg>Update atimer<commit_after>#ifndef _ATIMER_H
#define _ATIMER_H

#include <vector>
#include <thread>
#include <functional>
#include <boost/timer.hpp>
#include <boost/asio.hpp>

template<typename Duration = boost::posix_time::milliseconds>
class ATimer
{
public:
    ATimer() : m_timer(m_ios, Duration(0)) {}
    ~ATimer()
    {
        stop();
    }

    void start(unsigned int duration)
    {
        if (m_ios.stopped())
        {
            return;
        }

        m_duration = duration;
        m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
        m_func = [this]
        {
            m_timer.async_wait([this](const boost::system::error_code&)
            {
                for (auto& func : m_funcVec)
                {
                    func();
                }
                m_timer.expires_at(m_timer.expires_at() + Duration(m_duration));
                m_func();
            });
        };

        m_func();
        m_thread = std::thread([this]{ m_ios.run(); });
    }

    void stop()
    {
        m_ios.stop();
        if (m_thread.joinable())
        {
            m_thread.join();
        }
    }

    void bind(const std::function<void()>& func)
    {
        m_funcVec.emplace_back(func);
    }

private:
    boost::asio::io_service m_ios;
    boost::asio::deadline_timer m_timer;
    std::function<void()> m_func;
    std::vector<std::function<void()>> m_funcVec;
    std::thread m_thread;
    unsigned int m_duration = 0;
};

#endif
<|endoftext|>